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爲純數字

[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<<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報錯,此處直接去掉;  因爲&可以起到分割的作用

[root@Scott ~]# 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 "$@" --------取命令行傳參優先用這個就好了


20. function foo()在bash中沒有問題,但在其他shell中有可能出錯,所以不要把function和括號一起使用

直接foo()就好了


 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章