Shell脚本易犯的错

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为纯数字

[[email protected] ~]# f=123456

[[email protected] ~]# echo $f

123456

[[email protected] ~]# echo ${f##*[0-9]}

[[email protected] ~]# echo ${f#*[0-9]}

23456

7. grep foo file|while read line;do ((count++));done

执行之后count的值并没有变化,因为啊 | 管道就是一个shell子进程,子shell中的变量是无法传递出来的

[[email protected] ~]# grep s /etc/passwd|while read line;do ((count++));done

[[email protected] ~]# echo $count

[[email protected] ~]# 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<<eof也可以用 cat <<eof 此处是cat,不要搞成echo了

14. cd /foo;rm *:很危险的操作,因为/foo的foo可能不存在,那此句就会在/目录下删除

正确:cd /foo && rm *  ;根据cd的返回值执行多条语句可以这样cd /foo ||exit  1;cd .. rm ....

15. [ bar == "$foo" ]:学习的时候,就说的很明白。[]是不支持除=以外的比较符的,且=也只用在string的比较上

16. for i in {1..10};do something &;done报错,此处直接去掉;  因为&可以起到分割的作用

[[email protected] ~]# for i in {1..10};do echo 1 &;done

-bash: syntax error near unexpected token `;

17. cmd1 && cmd2 || cmd3:我很喜欢用,但当cmd2返回一个非0值,那么cmd3也是会被执行的

正确的是: if cmd1 ;then cmd2;else cmd3;fi

18. 在命令行 echo "hello!" 会报!的错误且不能\进行转义,但在shell脚本中没有这个错误

ifconfig 可以在命令行把ip给单独提取出来,但在shell脚本中是提取不出来的-----很蛋疼吧

19. for i in $*:错误点为 $*自己为一个string,当命令行参数有空格时,就会产生错误,

正确的做法 for i in "[email protected]" --------取命令行传参优先用这个就好了

20. function foo()在bash中没有问题,但在其他shell中有可能出错,所以不要把function和括号一起使用

直接foo()就好了

时间: 2024-10-07 08:40:32

Shell脚本易犯的错的相关文章

ubuntu14.04 shell脚本用select报错

在练习http://wiki.ubuntu.org.cn/Shell%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80中的select时,发现直接sh xx.sh不能执行成功. 脚本内容: #!/bin/bash echo "What is your favourite OS?" select var in "Linux" "Gnu Hurd" "Free BSD" "Other";d

shell脚本执行报错[: 0: unary operator expected

在执行shell脚本,if判断语句报错 #!/bin/bash if [ 0 == $testNum ] then echo "Check Result:0" fi testNum使用时没有定义,无赋值是空(原本是有定义的,只是笔误写错类似tsetNum了),执行转换后实际为 if [ 0 == ] 不相等,且少[符号错误:规避如下 #!/bin/bash if [[ 0 == $testNum ]] then echo "Check Result:0" fi 使用

shell脚本报错换行符syntax error near unexpected token \r

有时候一些windows下处理不当的sh脚本文件放到linux下执行报错, 提示存在换行符,原因主要就是window下EOL行结束是"\r\n"两个字符, 而linux,unix下是"\n"单字符. 以下vim命令做确认 :e ++ff=unix %    #显示回车符(\r), 具体的在vim环境中会显示为 "^M"符号 :set list    #显示换行符(\n), 具体的再vim环境下回显示为 "$" 符号. 此命令同

shell脚本在cygwin下运行报错: $&#39;\r&#39;: command not found

在cygwin 下运行shell脚本,出现"$'\r': command not found",这是win dos与Unix文本编辑方式不同造成的.可以使用cygwin工具dos2unix将script改为unix格式. $ dos2unix test.sh dos2unix: converting file test.sh to UNIX format ... $ sh test.sh 如此便可解决. 参见:http://lxs647.iteye.com/blog/2084375 s

执行shell脚本报错 &#39;\357\273\277&#39;: command not found 解决办法

1,删除BOM,在vi下面执行下面的命令即可 :set nobomb 2,原因: 所谓BOM,全称是Byte Order Mark,它是一个Unicode字符,通常出现在文本的开头,用来标识字节序(Big/Little Endian),除此以外还可以标识编码(UTF-8/16/32) 对于UTF-8/16/32而言,它们名字中的8/16/32指的是编码单位是多少位的,也就是说,它们的编码单位分别是8/16/32位,换算成字节就是1/2/4字节,如果是多字节,就要牵扯到字节序,UTF-8以单字节为

编写简单的shell脚本 - for循环 - 解决报错 Syntax error: Bad for loop variable

为了编写批量导入数据的程序,故而学习编写shell脚本!现学现用! ============================================ 1.第一个简单的for循环 #!/bin/bashfor i in 1 2 3 4;do echo $i;done 2.测试for的自增长的循环: #!/bin/bashfor ((i=1; i<=5; i++))do echo $i;done 如果会报错,没有则跳过: Syntax error: Bad for loop variable

shell脚本中报错dirname:无效选项 -- b

今天在写一个Shell脚本的时候,发现调试的时候会报一个错 [[email protected] autoawrrpt]$ . a.sh  dirname:无效选项 -- b 请尝试执行"dirname --help"来获取更多信息. basename:无效选项 -- b 请尝试执行"basename --help"来获取更多信息. 脚本内容如下: [[email protected] autoawrrpt]$ cat a.sh #!/bin/bash ######

Windows 和 Linux 中的换行与回车的区别,Windows下编写的Shell脚本,直接放到linux/unix下执行会报错

首先: CR(Carriage Return)表示回车 LF(Line Feed)表示换行 Dos和Windows采用回车+换行(CR+LF)表示下一行而UNIX/Linux采用换行符(LF)表示下一行苹果机(MAC OS系统)则采用回车符(CR)表示下一行 Windows下编写的Shell脚本,直接放到linux/unix下执行会报错,就是因为行结束符不一样导致的. 现在好多文本工具都提供了转换功能,如我常用的,也是最强大的工具 (个人感受,不是打广告):notepad++. 原文地址:htt

shell脚本运行报错$&#39;\r&#39;: command not found

执行个别shell测试脚本运行报错$'\r': command not found 考虑到可能是windows与Linux的换行符不同的原因(windows是\r\n,Linux是\n)造成的,但是又不想一个个替换. 可以使用如下命令来解决: # vi 脚本名 命令行模式下输入: :set ff=unix :wq 退出即可 shell脚本运行报错$'\r': command not found 原文地址:https://www.cnblogs.com/abclife/p/12604441.htm