3 回答

TA貢獻2039條經驗 獲得超8個贊
在每個命令之后,都可以在$?變量中找到退出代碼,因此您將獲得以下內容:
ls -al file.ext
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
您需要注意管道命令,因為$?唯一命令會為您提供管道中最后一個元素的返回代碼,因此,在代碼中:
ls -al file.ext | sed 's/^/xx: /"
如果文件不存在,則不會返回錯誤代碼(因為sed管道的一部分實際起作用,返回0)。
該bash殼實際上提供一種陣列,其可以協助在這種情況下,即是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值,則將其存儲在其中。

TA貢獻1853條經驗 獲得超6個贊
如果要使用$ ?,則需要在每個命令后進行檢查,因為$?每個命令退出后更新。這意味著,如果您執行管道,則只會獲取管道中最后一個進程的退出代碼。
另一種方法是這樣做:
set -e
set -o pipefail
如果將其放在shell腳本的頂部,則bash似乎會為您解決這個問題。如前所述,“ set -e”將導致bash退出并在任何簡單命令上出現錯誤?!?set -o pipefail”也將導致bash退出,并且管道中的任何命令也會出錯。
有關此問題的更多討論,請參見此處或此處。 這是內置的bash手冊部分。
添加回答
舉報