コマンドを検討する
eval false || echo ok
echo also ok
false
通常、これによりユーティリティが実行され、終了ステータスがゼロでないため、およびが実行されるecho ok
と考えられますecho also ok
。
私が使用しているすべての POSIX ライクなシェル ( ksh93
、、、OpenBSD 、および) では、これが起こりますが、 を有効にすると興味深いことが起こりzsh
ます。bash
dash
ksh
yash
set -e
set -e
が有効な場合、OpenBSD のsh
およびksh
シェル (両方とも から派生pdksh
) は を実行するときにスクリプトを終了しますeval
。他のシェルではこれを行いません。
POSIXによれば特別な組み込みユーティリティ (などeval
) でエラーが発生すると、非対話型シェルが終了するはずです。 を実行することがfalse
「エラー」を構成するかどうかはよくわかりません (そうであれば、アクティブであることとは無関係ですset -e
)。
これを回避するには、eval
サブシェルに
( eval false ) || echo ok
echo also ok
問題は、これを POSIX 準拠のシェル スクリプトで行う必要があるのか、それとも OpenBSD のシェルのバグなのかということです。また、上記にリンクされている POSIX テキストの「エラー」とはどういう意味ですか。
追加情報: OpenBSDシェルは コマンドの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
答え1
他のシェルではこのような回避策が必要ないということは、それが OpenBSD ksh のバグであることを強く示唆しています。実際、ksh93 ではこのような問題は発生しません。
コマンドラインにがある場合、||
その左側の戻りコード 1 によって発生するシェルの終了を回避する必要があります。
エラー特別組み込みは非対話型シェルを終了させるPOSIXによるとしかし、それは常に正しいわけではありません。continue
ループから抜けようとするとエラーになり、これはcontinue
組み込みのエラーです。しかし、ほとんどのシェルは次のような場合には終了しません。
continue 3
明確なエラーを発行するが終了しない組み込み関数。
したがって、 exit on は、コマンドの組み込み特性 (この場合は)ではなくfalse
条件によって生成されます。set -e
eval
POSIX では、終了する正確な条件はset -e
かなり曖昧です。
答え2
[これが本当の答えでなければ申し訳ありません。時間ができたら更新します]
ソースコードを見て、次のような結論に達しました。
1) これはバグ/制限であり、その背後に哲学的な根拠は何もありません。
mksh
2) OpenBSDのksh ( )のポータブルフォークからの「修正」は、とても残念なことに、事態を悪化させるだけで、実際には解決しません。
他のすべてのシェルとは異なる新しいバグ:
mksh -ec 'eval "false; echo yup"'
yup
bash -ec 'eval "false; echo yup"'
(nothing)
まだ完全には修正されていません:
mksh -ec 'eval "set -e; false" || echo yup'
(nothing)
bash -ec 'eval "set -e; false" || echo yup'
yup
bash
上記をdash
、、、などに置き換えることができますzsh
。yash
ksh93