似乎好像大概有句話是這么說得,好程序與壞程序之間的區別就在於它的魯棒性,也就是在異常情況下該程序是否還是在可hold住狀態,能否不死,不崩潰,或者不做出一些超出預期的事情。那要做好這些,自然而然就要學會如何去處理異常。平時寫php或者java程序等等的時候,很多人都會去注重對於異常的處理,比如try..catch等等,但往往在寫一些腳本的時候,忽視了對於異常的判斷。本文主要就是寫如何在shell中去處理異常。因為今天太晚了,所以我就先寫第一部分,后面再寫第二部分。
返回值
要判斷一段代碼是否出現了異常,一個最基本的判斷就是對他返回值的判斷。在shell中,我們往往規定0為正常,一切非0返回值則為不正常。但往往我們在寫
shell腳本的時候,忽略對於返回值的判斷。我們看一個很基本的
shell程序
#!/bin/sh
cd /home/xxxx/
rm -rf *
這個腳本的意思很簡單,就是cd到某一個目錄下,然后將該目錄下所有的內容都刪除。首先,rm這種東西出現在腳本中,就是一個很危險的操作,而這個程序的關鍵之處還在於,並沒有對第一行shell的返回值進行任何的判斷,也就是說對於cd那行代碼無論執行失敗與否,都會去執行下面的那段rm,試想如果在某些情況下cd那段代碼失敗了之后,會出現多么可怕的后果。所以,我們應該對於cd的代碼做返回值的判斷。
#!/bin/sh
cd /home/xxxx/
if [ "$?"= "0" ]; then
rm -rf *
else
echo "cannot change directory" 1>&2
exit 1
fi
$?這個常量代表的就是上一段shell的返回值。這個我在前面一片文章里也提到過shell中的trap和expr。這樣寫的話,就要比先前的程序安全多了,如果沒有cd到相應目錄,則不會去執行刪除操作。
當然,程序里這樣寫是有些負責了,其實你也可以這樣寫:
if cd /home/xxxx/ ; then
rm -rf *
else
echo "cannot change directory" 1>&2
exit 1
這是if的另一種用法。這樣寫,就要比剛才的好多了。不過其實這樣寫,也比較麻煩,其實你還可以這樣來寫:
cd /home/xxxx/ && rm -rf *
這個&&符大家肯定不陌生,那這樣來寫,是否就可以保證了程序的安全性了呢?下面就來講一下&&和||
&&和||
對於一個
shell程序, shell1 && shell2 ,如果是用&&符連接的,那只有在shell1返回0(即正常)時,shell2才會執行,否則shell2根本就不執行,所以前面說得最后一種cd&&rm的這種做法是可行的,而且是安全的。那||呢,對於shell1||shell2,只有在shell1執行失敗時,shell2才會執行,否則shell2是不執行得。所以,我們可以這樣來寫:
cd /home/xxxx || error_exit "Cannot change directory"
rm -rf *
這樣,在cd /home/xxxx失敗時,就會進行error_exit這個函數的分支。那error_exit這個是啥函數呢。。哦,其實,這只是一個自定義的失敗處理函數而已。一個比較簡單的定義,當然,這也是處理程序異常的一個方式。因為總不能每次異常,都去手動寫個echo failed exit等等,所以有個統一的函數處理會比較方便。
function error_exit {
echo "$1" 1>&2
exit 1
}
cd /home/xxxx || error_exit "failed"
rm -rf *
如上,這是一個非常簡單的異常處理函數,在異常時,可以去主動調用error_exit,當然,你調用的時候,可以補充上行號信息。比如:
cd /home/xxxx || error_exit "$LINENO: failed"
上面講得只是一些簡單的異常處理的方式,其實還有其他方式,比如我在上篇文章shell中的trap和expr講到的trap方式,其實也正是因為我上面文章寫了trap,所以才想寫這篇文章來把處理shell的異常給整理出來,當然也是為大家提個醒,在shell中,也是要處理異常,需要有這樣一個意識。今天太晚了,先睡覺了,明早還要早起T.T ,下篇文章,PART 2中,我會詳細總結下trap的捕獲異常的方式。
轉載,僅供參考,祝你愉快,滿意請采納。
