寻觅生命中的那一片浅草......

每月存档 一月, 2010

sed删除某关键字的下一行到最后一行

[root@test200 ~]# cat test
a
b
c
d
e
f
[root@test200 ~]# sed ‘/c/{p;:a;N;$!ba;d}’ test
a
b
c

定义一个标签a,匹配c,然后N把下一行加到模式空间里,匹配最后一行时,才退出标签循环,然后命令d,把这个模式空间里的内容全部清除。

if 匹配”c”
:a
追加下一行
if 不匹配”$”
goto a
最后退出循环,d命令删除。

当while遇到重定向—-sh的陷阱

以下是我在编程时的亲身体会:
先看如下的程序:
#!/bin/sh

count=0
while read LINE
do
count=`expr $count + 1`
done < file
echo $count
问题是这个程序能得到什么样的结果?仿佛很明显,能够统计文件file的行数,然而你若执行一下便知,无论file的行数是多少,该程序的输出始终是0!为什么?
原来如果使用for,while,until,if,case这些命令时用到了重定向,那么sh会产生一个子shell来运行它们。可以想象count在循环体中能够正确的计数,一旦while执行完毕,子shell完成,其内部的变量count就消失了。因而得到的结果是循环体外开始赋的值0!
可以避免吗?试试这样:
cat file|while read LINE
do
count=`expr $count + 1`
done
echo $count
依然如此!怎么办?可以先关闭标准输入,然后以你要读取得文件重新打开它,这样就不需要对while命令的输入进行改向,也就不会用子shell的方式来运行它了。如下:
exec<file
count=0
while read LINE
do
count=`expr $count + 1`
done
exec < /dev/tty
echo $count
也可以
exec 4<&amp;0 0< file
count=0
while read LINE
do
count=`expr $count + 1`
done
exec 0<&amp;4
echo $count
如果还有怀疑的话可以试一下if:
#!/bin/sh

echo &quot;abcd&quot;|if [ &quot;abcd&quot; = &quot;abcd&quot; ]; then
var=7
fi
echo $var
输出当然是空。去掉echo &quot;abcd&quot;|就好了。
所以不了解这一点在编程时就会非常危险,试想while,for,case,if,until是多么的常用,与管道或重定向连着用也是很常见的,可是一旦在其内部使用了什么变量,就是有进无出,有去无回了。
以上的说法仅限于sh编程,对于ksh,bash,据我所知都不会有这个问题,它们处理的时候不会当作子shell来做。其它种类的shell可以自己试一试。

当while read 遇上ssh

http://hi.baidu.com/test/blog/item/16ecf01f6f46e4f7e0fe0b10.html

当while read 遇上ssh
2007-08-15 21:13先看一段简化过的BASH SHELL代码

TODAY=`date +%Y%m%d`
SUFFIX=”tar”
CONF=the_config_file
i=0

while read HOST SRCPATH DSTPATH
do
(( i++ ))
if [ “X${HOST:0:1}” = “X#” -o ${#DSTPATH} -eq 0 ]
then
#忽略注释行及少于3个项的记录
else
ssh ${HOST} “tar c ${SRCPATH}” >${DSTPATH}.${TODAY}.${SUFFIX} 2>/dev/null
fi
done < $CONF

作者的本意是通过脚本读取配置文件$CONF,然后打包备份$CONF中指定的文件,但执行后发现程序在成功备份$CONF中指定的第一个文件后即退出……

跟踪后发现read在备份完第一个文件后就再读不到任何数据,所以while循环结束--也就是说,
通过重定向$CONF文件传给标准输入的数据被

ssh ${HOST} “tar c ${SRCPATH}” >${DSTPATH}.${TODAY}.${SUFFIX} 2>/dev/null

这个命令提前吃掉了。

将其改为
ssh ${HOST} “tar c ${SRCPATH}” >${DSTPATH}.${TODAY}.${SUFFIX} 2>/dev/null </dev/null

将ssh的标准输入重定向到/dev/null,程序正常备份所有$CONF中指定的文件。

while read line的一些问题

while read line的一些问题

Q1. 曾经面试的时候被问到一个问题, 说
while read line ; do
echo $line ;
done < ./a.txt
失败, 会是什么原因, 当时觉得不太可能, 就回答了“我用的时候没有碰到过这种情况”。 前段在写一个脚本的时候, 确实遇到了所谓的while read 失败, 原因是我读入的文件是在win下用dos格式保存的文本, 所以每行结束都带有一个\r字符, 这个字符在linux/unix环境下的作用是“回到一行的开始”, 如果再对$line做相关的字符串操作的话(比如字符串连接), 得到的结果可能会让人迷惑… 所以当把win下编译的文本用在linux/unix环境时, 最好做一下格式转换

Q2. 2009-08-01更新:
# cat ur_file
1234 abcd
5678 efgh

# vi t3.sh
#!/bin/bash

while read t1 t2 ; do
echo $t1 $t2 ; awk ‘{ print $0 }’
done < ./ur_file

#./t3.sh
1234 abcd
5678 efgh

# sh -x ./t3.sh 发现只read 了一次

Q3.

# seq 10 > file
# while read line ; do
> echo $line
> dd &>/dev/null
> done < ./file
1

为什么这里只打印第一行呢?
问题的关键在于:
read从输入读取了一行内容后,
其它的程序(比如 rsh或sed)从同样的地方把其它的输入读走了,
read当然读不到其它内容了,
while也就结束了

摘自:http://bbs.chinaunix.net/viewthread.php?tid=769040&extra=&page=2

可以打开set -x, 看看, 确实只read了两次, 第一次read出第一行, 第二次read不到就退出while循环
read 和 dd都从文件描述符3中读取数据

MySQL – Got a packet bigger than ‘max_allowed_packet’

The default maximum allowed packget size is 1MB, so if you store some large binaries in your database you might get some problems. All you need to do is re-set the maximum size to a larger number.

Macintosh:trunk jennyfong$ mysql -uroot database_name < database_backup.sql

ERROR 1153 (08S01) at line 2365: Got a packet bigger than ‘max_allowed_packet’ bytes
Macintosh:trunk jennyfong$ mysql -uroot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 5.0.86 MySQL Community Server (GPL)

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

mysql> set global net_buffer_length=10000000;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> set global max_allowed_packet=1000000000;
Query OK, 0 rows affected (0.00 sec)

mysql> exit
Bye
Macintosh:trunk jennyfong$ mysql -uroot database_name < database_backup.sql

show variables like ‘max_allowed_packet’;

2010年一月
« 12月   2月 »
 123
45678910
11121314151617
18192021222324
25262728293031