2011-07-08 98 views
1

我想在循環中的任何命令返回1時在循環塊代碼上出錯和出錯。我想在沒有子shell的情況下執行此操作。在bash中的代碼塊上出錯

while read file; do 

    command_one_that_might_error_out; 
    command_two_that_might_error_out; 
    command_three_that_might_error_out; 

done < <(ls -1 .) || echo "something bad when of the commands ran happened"; 

任何人都可以提供見解嗎?

回答

1

我沒有測試過,但這應該工作:

err_val=0 
while read file; do 

    command_one_that_might_error_out || { err_val=$?; break; } 
    command_two_that_might_error_out || { err_val=$?; break; } 
    command_three_that_might_error_out || { err_val=$?; break; } 

done < <(ls -1 .) 

if [ $err_val -ne 0 ]; then 
    echo "something bad happened" 
fi 
0

最簡單的方法可能使用$?,這是最後一個命令的返回值。所以你可以添加

if [[ "$?" = "1" ]]; then 
    break 
fi 

之後的每個命令。

+0

這恐怕反成語尖叫「我不是一個好殼的程序員」,用的情況下,可能是個例外,你專只想在錯誤代碼1上打破,但將所有其他錯誤代碼作爲成功傳遞。 (即使這樣,我會使用'case',並且/或者嘗試重構循環。) – tripleee

1

嘗試set -e在腳本的頂部。當你在它set -u是一般良好的bash衛生。

+1

我在Bash 4.1.5的'man'頁面中看不到'-w',或者在[Google搜索](https://encrypted.google.com/search?q=%22set+-w%22+bash)。你可能是指'pipefail'還是'noclobber'? – l0b0

+0

右l0b0,我的錯誤 - 我用Perl的-w交叉授粉。 – srking

1

您可以在每個命令的末尾放置|| break,但break返回0,因此您的最終|| echo "something bad happened"將不會執行。

您可以使用break 0break將以非零代碼退出,但它也會寫入一個錯誤(可能會重定向)。您可以通過一個全局變量傳播錯誤代碼,如Gordon Davisson的答案所示。

你可以在一個函數把break命令,使這個少許清潔劑並捕獲ERROR_CODE太:

break_fail() { break 0 2>/dev/null ; } 
break_error() { error_code=$? ; break 0 2>/dev/null ; } 

error_code=0 
while read file; do 
    command_one_that_might_error_out || break_error 
    command_two_that_might_error_out || break_error 
    command_three_that_might_error_out || break_error 
done < <(ls -1 .) || echo "something bad happened: Error $error_code" 

這並不是告訴你哪些命令,雖然返回的錯誤。

如果你需要處理特定的錯誤代碼,我建議在循環中內聯處理它們並用break_fail打破。

+0

非常感謝你這是非常好的。我認爲那個傳遞錯誤的人幫助我多一點。希望我可以標記兩個答案。 – storkk