Bash

bash -e 和 && 在函式內部求值

  • April 29, 2021

設置選項時,我對 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關鍵字之後的命令列表的一部分、在ifor保留字之後的測試的一部分、在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

引用自:https://unix.stackexchange.com/questions/647179