Posix

條件表達式中“set -e”下“eval”的行為

  • June 10, 2019

考慮命令

eval false || echo ok
echo also ok

通常,我們希望它執行false實用程序,並且由於退出狀態非零,然後執行echo okand echo also ok

在我使用的所有類似 POSIX 的 shell(、、、、、OpenBSD和)ksh93zsh,都會發生這種情況bash,但如果我們啟用.dash``ksh``yash``set -e

如果set -e生效,OpenBSDshkshshell(均源自pdksh)將在執行eval. 沒有其他外殼可以做到這一點。

POSIX 表示特殊內置實用程序(例如eval)中的錯誤應該導致非互動式 shell 終止。我不完全確定執行是否false構成“錯誤”(如果是,它將與set -e活動無關)。

解決此問題的方法似乎是將其放入eval子外殼中,

( eval false ) || echo ok
echo also ok

問題是我是否應該在一個 POSIX-ly 正確的 shell 腳本中這樣做,或者這是否是 OpenBSD 的 shell 中的一個錯誤?另外,上面連結的 POSIX 文本中的“錯誤”是什麼意思?


額外資訊:OpenBSD shell 將 在命令中執行echo ok有和無set -e

eval ! true || echo ok

我的原始程式碼看起來像

set -e
if eval "$string"; then
   echo ok
else
   echo not ok
fi

使用OpenBSD 外殼不會輸出(它會終止),我不確定這是設計使然,錯誤或誤解,還是其他原因。not ok``string=false

沒有其他 shell 需要這種解決方法,這強烈表明它是 OpenBSD ksh 中的一個錯誤。事實上,ksh93 並沒有顯示出這樣的問題。

命令行中有 a||一定要避免左側返回碼 1 導致的 shell 退出。

根據POSIX ,特殊內置的錯誤將導致非互動式 shell 退出,但這並不總是正確的。試圖跳出循環是錯誤的,並且是內置的。但大多數外殼不會退出:continue``continue

continue 3

發出明確錯誤但不退出的內置函式。

因此,退出false是由set -e條件而不是命令的內置特性生成的(eval在這種情況下)。

在 POSIX 中退出的確切條件set -e相當模糊。

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