我们在写脚本的时候,会遇到各种各样的问题,一不留神就会跌坑,我们总结经验,吸取教训,总之就是为了避免再次踩雷~
1。在while命令和管道符相结合时,系统会fork一个子进程来执行while命令。
================================
var=0
echo 123 | while read line
do
var=1
break
done
echo $var
================================
该命令执行的结果为0,而不是123
这是因为while是在子进程中执行的,当子进程退出是,var=1也就无疾而终了
http://blog.csdn.net/zhuying_linux/article/details/68914362
2。在while命令中,标准输入被重定向
================================
echo xxx | while read line
do
select var in a b c
do
break
done</dev/null
done
================================
该命令组合的执行结果,并不会让你进行选择,因为标准输入已经重定向为管道符的位置了。
**********************************************************
while read line
do
ssh $ip“ls "</dev/null
sleep1
done<file
**********************************************************
无论file文件中有多少行,ssh命令执行完一次之后都会停止,因为ssh读走了所有的标准输入
同样的,有很多类似的命令都可以从标准输入中读取命令
正确的写法需要添加红色部分,当然,如果将ssh命令写在一个脚本中执行,同样存在这样的情况,这将为我们的排错带来相当大的困扰。
当然也可以用管道命令,如下所示:
*********************************************************
grep -v '^#' apache.properties| while read i
do
myip=`echo $i | awk '{print$1}'`
ssh $myip "ls"</dev/null
sleep1
done
*********************************************************
像上面这个,如果有多个ip,在你没有加</dev/null的时候,可能不会报错,但是函数执行的时候,你会发现循环只进行了一次,这就是关键原因。
3。关于IFS变量
很多时候我们喜欢这样使用for命令
================================
for var in `ls`
do
echo $var
done
================================
这当然是没有什么问题的
不过for的默认分隔符是空格和制表符等
如果需要使用换行为分割,则我们通常会用这样的方式
================================
IFS='$'
for var in `ls -lhrt | awk '{ print $9 }'`
do
a="cp $var $var.bak"
$a
done
================================
好吧,根据我们的经验,这个脚本的用途是备份当前目录下的文件,可是实际上呢,执行的时候会出现执行错误
因为$a并非我们想象的
cp file file.bak
而是
'cp file file.bak'
IFS='$'时,系统已经悄悄的为变量的两边添加了''
执行命令的时候,系统解析不了单引号中的命令