条件式の「set -e」の下の「eval」動作

条件式の「set -e」の下の「eval」動作

コマンドを考える

eval false || echo ok
echo also ok

通常、ユーティリティを実行し、false終了ステータスがゼロではないため、echo okおよびを実行しますecho also ok

これは私が使用しているすべてのPOSIX様シェル(ksh93、、 OpenBSD zshbashおよび)で発生しますが、これを有効にすると状況が面白くなります。dashkshyashset -e

set -e有効な場合、OpenBSDshkshシェル(両方から派生pdksh)が実行されますeval。他のシェルはこれを行うことはできません。

POSIX と特別な組み込みユーティリティ(例:)evalのエラーのため、非対話型シェルを終了する必要があります。実行が「エラー」を構成しているかどうかは完全にはわかりません(そうであれば、falseアクティブ状態とは何の関係もありません)。set -e

evalこの問題の解決策はサブシェルに入れることです。

( eval false ) || echo ok
echo also ok

問題は、POSIX正しいシェルスクリプトでこれを行う必要がありますか、それともOpenBSDシェルのバグですか?また、上記のPOSIXテキストで「エラー」とはどういう意味ですか?


echo ok追加情報:OpenBSDシェルは、コマンドを使用または使用せずに実行されます。set -e

eval ! true || echo ok

私の元のコードは次のとおりです。

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

これはいいえnot okOpenBSDシェルの出力string=false(終了)を使用すると、これが意図的なものか、バグや誤解なのか、それとも別のものかはわかりません。

答え1

他のシェルにはこれらの回避策は必要ありません。これは、これがOpenBSD kshのバグであることを強く示唆しています。実際、ksh93にはそのような問題はありません。

||シェルを終了させる戻りコードが左側に1になるのを避ける必要があるコマンドラインがあります。

エラーは次のとおりです。特別な組み込みにより非対話型シェルが終了します。POSIXによるとしかし、必ずしもそうではありません。continueループから抜け出そうとするのはエラーで、continue組み込みです。ただし、次の状況では、ほとんどのシェルは終了しません。

continue 3

明らかなエラーを発生させるが終了しない組み込み関数です。

したがって、終了はコマンドの組み込み機能(この場合)ではなく条件によって生成されますfalseset -eeval

POSIXでは、正確な終了条件はやや曖昧ですset -e

答え2

[実際の回答でない場合は申し訳ありません。時間が経つと更新します。]

ソースコードを見て、結論はこうです。

1)これはバグ/制限事項であり、その後には哲学的な意味はありません。

2)OpenBSD ksh()のポータブルブランチでは、これに対する「修正」は次mkshのとおりです。非常にこのように、実際に問題を解決しないと状況がさらに悪化するだけです。

他のすべてのシェルとは異なる新しいエラー:

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に変更できます。dashzshyashksh93

関連情報