條件表達式中“set -e”下“eval”的行為
考慮命令
eval false || echo ok echo also ok
通常,我們希望它執行
false
實用程序,並且由於退出狀態非零,然後執行echo ok
andecho also ok
。在我使用的所有類似 POSIX 的 shell(、、、、、OpenBSD和)
ksh93
中zsh
,都會發生這種情況bash
,但如果我們啟用.dash``ksh``yash``set -e
如果
set -e
生效,OpenBSDsh
和ksh
shell(均源自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
相當模糊。