|
shell脚本的易犯错误
1. for i in x y z : 这句是以空格作为分隔符的,当我们的$n中包含空格的话,就会有错误
如 for i in `ls *.mp3` ,这句 ls *.mp3执行后如果有空格就gg了
直接 for i in *.mp3 就好了
2. cp $file $target :当$file中有空格时就会出错
正确: cp "$file" "$target"
但是$file为-开头的话,会被当作命令行选线处理,就像 cp -ap $1 $2中的-ap一样
完全的方法:用for循环
for i in ./*.mp3;do cp "$i" /$target;done
小结:在shell脚本中遇到$n需要注意空格问题,一般来说,变量要用""做处理
总的来说,在命令如cd 直接操作之前,进行过换算的如$或者``,都需要注意空格问题
3.[ "$foo" = "bar" ]:当$foo以-开头时,会报错。
[[能正确处理空格,空白,带横线等问题
正确:[[ $foo = bar ]],当然 [ bar = "foo" ]也可以
4. cd `dirname "$f"`:当路径中含有空格时,就会出错,处理方式类型为上面进行的总结
正确:cd "`dirname "$f"`" 在shell中""是进行的由内往外的匹配,这点与c语言中的就近匹配是不一样的
5. [ bar = "$foo" && foo = "$bar" ]:在学习shell中,我们把test与[]对比学习的,这两者是一致的,所以把该式子变换为test bar = "$foo" && foo = "$bar"这其实是两个式子了
正确的 [ bar = "$foo" -a foo = "$bar" ] 或者[[ bar = "$foo" && foo = "$bar" ]] 或者 [ bar = "$foo"]&&[ foo = "$bar" ]
6.[[ $f > 7 ]]:很遗憾呢,[[不能用作数字的比较,之前都没注意过,因为都不用
(($f>7))或我经常用的[ "$f" -gt 7 ],不过先要判断$f是数字,不然也会出错呢。-----${string##*[0-9]}是否为空,为空就说明$string为纯数字
[root@Scott ~]# f=123456
[root@Scott ~]# echo $f
123456
[root@Scott ~]# echo ${f##*[0-9]}
[root@Scott ~]# echo ${f#*[0-9]}
23456
7.grep foo file|while read line;do ((count++));done
执行之后count的值并没有变化,因为啊 | 管道就是一个shell子进程,子shell中的变量是无法传递出来的
[root@Scott ~]# grep s /etc/passwd|while read line;do ((count++));done
[root@Scott ~]# echo $count
[root@Scott ~]# grep s /etc/passwd|while read line;do ((count++));echo $count|tr "\n" " ";done
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
8.if [grep s /etc/passwd]:if后面接一个判断语句,它会将if与then之间的所有命令返回值当作判断条件
但[]是一个语法,他并不是if的一部分,二者无必然联系
所以上面的应该写成 if grep s /etc/passwd >/dev/null;then ..
9.if [[ a = b ]&&[ c = d ]];then:理由同上 应改为 if [ a = b ]&&[ c =d ];then
10.sed 's/foo/bar/g' file >file :不能从一个文件读,然后直接就修改,但我记得sort有参数-o可以
11.echo $foo
MSG="please enter a file form like *.zip"
echo $MSG时,会出现*.zip匹配A.zip的情况,正确的做法是 echo "$MSG"
12.foo = bar 或 $foo=bar: 变量赋值时,正确为foo=bar 不要空格,这不是c语言
13.cat >>file |
|
|
|
|
|
|