bash -e 和 && 在函式內部求值
設置選項時,我對 bash(和破折號)行為感到困惑
-e
。簡單的例子:
#!/bin/bash -e func() { false && true } false && true echo "1" func echo "2"
輸出:
1
預期輸出:
1 2
雖然第一次出現按預期工作,但第二次出現(函式內部)導致立即退出。我搜尋了文件,但無法找到對這種不同行為的解釋。這背後有什麼理由嗎,還是這個錯誤?我在 bash 和 dash 中對此進行了測試,結果相同。
根據 bash 手冊頁:
-e
如果管道(可能由單個簡單命令組成)、列表或複合命令(參見上面的 SHELL GRAMMAR)以非零狀態退出,則立即退出。while
如果失敗的命令是緊跟在oruntil
關鍵字之後的命令列表的一部分、在if
or保留字之後的測試的一部分、在or列表elif
中執行的任何命令的一部分,除了最後or之後的命令,則 shell 不會退出 ,任何管道中的命令但最後一個,或者如果命令的返回值與. 如果子 shell 以外的複合命令由於命令在被忽略時失敗而返回非零狀態,則 shell 不會退出。一個陷阱&&``||``&&``||``!``-e``ERR
,如果設置,則在 shell 退出之前執行。該選項分別適用於 shell 環境和每個子 shell 環境(參見上面的命令執行環境),並且可能導致子 shell 在執行子 shell 中的所有命令之前退出。如果復合命令或 shell 函式在
-e
被忽略的上下文中執行,則在復合命令或函式體中執行的任何命令都不會受到-e
設置的影響,即使-e
設置了並且命令返回失敗狀態。如果復合命令或 shell 函式在被忽略-e
的上下文中執行時-e
設置,則在復合命令或包含函式呼叫的命令完成之前,該設置將不起作用。
該腳本在從 返回時終止
func
,因為它的退出狀態為非零。腳本沒有在內部終止func
。該
false && true
列表不受 影響-e
,並且腳本不會從它終止,不在腳本的主要部分中,也不在函式中。但是,
false
函式中的 將函式的退出狀態設置為非零,因此當函式返回時,shell 終止。您的腳本可以簡化為
#!/bin/bash -e false && true echo "1" false echo "2"
您可能還想測試從函式返回零,以說服自己函式中的
false && true
列表沒有終止腳本:#!/bin/bash -e func() { false && true return 0 } false && true echo "1" func echo "2"
執行此輸出
1 2