我有一個執行許多命令的shell腳本。 若是任何命令以非零退出代碼退出,如何使shell腳本退出? html
http://cfaj.freeshell.org/shell/cus-faq-2.html#11 shell
如何在cmd1|cmd2
獲取cmd1
的退出代碼 數組
首先,請注意cmd1
退出代碼可能不爲零,但仍然不表明錯誤。 例如,這發生在 bash
cmd | head -1
您可能會觀察到cmd1
的141(或269與ksh93)退出狀態,但這是由於當讀取一行後頭head -1
終止時, cmd
被SIGPIPE信號中斷。 spa
要知道管道元素cmd1 | cmd2 | cmd3
的退出狀態 cmd1 | cmd2 | cmd3
code
一個。 用zsh: htm
退出代碼在pipestatus特殊數組中提供。 cmd1
退出代碼在$pipestatus[1]
, cmd3
退出代碼在$pipestatus[3]
,這樣$?
始終與$pipestatus[-1]
。 ip
灣 用bash: get
退出代碼在PIPESTATUS
特殊陣列中提供。 cmd1
退出代碼在${PIPESTATUS[0]}
, cmd3
退出代碼在${PIPESTATUS[2]}
,因此$?
老是與${PIPESTATUS: -1}
。 cmd
...
有關詳細信息,請參閱如下連接 。
[ $? -eq 0 ] || exit $?; # exit for none-zero return code
在bash中這很容易,只需用&&將它們綁在一塊兒:
command1 && command2 && command3
您還可使用嵌套的if結構:
if command1 then if command2 then do_something else exit fi else exit fi
在每一個命令以後,能夠在$?
找到退出代碼$?
變量,因此你會有這樣的東西:
ls -al file.ext rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
你須要當心管道命令,由於$?
只提供管道中最後一個元素的返回碼,所以,在代碼中:
ls -al file.ext | sed 's/^/xx: /"
若是文件不存在,則不會返回錯誤代碼(由於管道的sed
部分實際工做,返回0)。
bash
shell實際上提供了一個能夠幫助處理PIPESTATUS
。 此數組爲每一個管道組件都有一個元素,您能夠像${PIPESTATUS[0]}
同樣單獨訪問:
pax> false | true ; echo ${PIPESTATUS[0]} 1
請注意,這會使您得到false
命令的結果,而不是整個管道。 您還能夠根據須要獲取整個列表進行處理:
pax> false | true | false; echo ${PIPESTATUS[*]} 1 0 1
若是您想從管道中獲取最大的錯誤代碼,可使用如下內容:
true | true | false | true | false rcs=${PIPESTATUS[*]}; rc=0; for i in ${rcs}; do rc=$(($i > $rc ? $i : $rc)); done echo $rc
這依次遍歷每一個PIPESTATUS
元素,若是它大於前一個rc
值,則將其存儲在rc
。
「 set -e
」多是最簡單的方法。 只需將它放在程序中的任何命令以前。