我set -e
習慣於出現第一個錯誤時停止 bash 腳本。
一切正常,除非我使用以下命令&&
:
$ cat script
set -e
cd not_existing_dir && echo 123
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
I'm running! =P
$
和....相比:
$ cat script
set -e
cd not_existing_dir
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
$
第一個範例仍然會回顯I'm running!
,但第二個範例不會。為什麼他們的行為會不同?
UPD。類似問題:https://stackoverflow.com/questions/6930295/set-e-and-short-tests
答案1
這是有記錄的行為。這bash(1) 手冊頁說,對於set -e
,
while
如果失敗的命令是緊接在or關鍵字之後的命令清單的一部分,是緊接在或保留字until
之後的測試的一部分,則 shell 不會退出,if
elif
&&
或||
清單中執行的任何命令的一部分&&
除了最後一個或 之後的命令||
,管道中除最後一個命令之外的任何命令,或命令的返回值與!
.
[強調。
還有POSIX外殼命令語言規格 確認這是正確的行為:
當執行、、或保留字之後的複合清單、以保留字開頭的管道或 AND-OR 清單中除最後一個命令之外的任何命令
-e
時,應忽略該設定。while
until
if
elif
!
和第2.9.3節清單該文件的定義
&&
AND-OR 清單是由運算子「 」和「 」分隔的一個或多個管道的序列||
。
答案2
該set -e
選項在某些情況下不起作用,這是標準行為,並且可以跨 POSIX 相容 shell 移植。
失敗的命令是管道的一部分:
false | true; echo printed
將列印printed
.
並且只考慮管道本身的故障:
true | false; echo 'not printed'
不會列印任何內容。
失敗的命令在while
、until
、if
、elif
保留字之後的複合列表中運行,以保留字開頭的管道,或者作為除最後一個之外的!
一部分&&
或列表的任何命令:||
false || true; echo printed
最後一個命令失敗仍然會受影響set -e
:
true && false; echo 'not printed'
這子外殼複合命令失敗:
(false; echo 'not printed') | cat -; echo printed
答案3
我的猜測是 if-then 條件作為一個整體評估為 true。
我試過
set -e
if cd not_existing_dir
then echo 123
fi
echo "I'm running! =P"
誰給
-bash: cd: not_existing_dir: No such file or directory
I'm running! =P
錯誤代碼被 if 條件捕獲,因此 bash 不會觸發執行結束。