エラー状態を保存し、追加のコードを実行し、エラー状態を元のエラー状態に設定する小さなスクリプトを作成したいと思います。 Bashでは:
<< some command >>; _EXIT=$?;( <<other code here>> ;exit $_EXIT)
ただし、必要なコードは、bash、zsh、csh、または tcsh で実行されているかどうかに関係なく実行できます。どのシェルを使用するかは、ユーザーが決めるのであらかじめわかりません。 <<aコマンド>>もユーザーが決定します。
<<他のコード>>がすべてのシェルで動作すると仮定することは安全ですが、ファイルに書き込むことができると仮定することは安全ではありません(したがってファイルに入れることは機能しません)。
背景
GNU Parallel は、ユーザーが決定したシェルでユーザーが指定したコマンドを実行します。コマンドが完了したら、GNU Parallelはいくつかのクリーンアップ操作を実行する必要があります。同時に、GNU Parallelはユーザーが提供したコマンドの終了値を覚えておく必要があります。上記のスニペット以前に実行されたコードは、ユーザーが提供したコマンドでした。 <<他のコード>>はクリーンアップコードです。
答え1
この答えはbashのようなシェルとcshのようなシェルの両方で動作し、Perlは必要ありません。
sh -c '<< other code >>; [ "$0" != "" ] && exit "$0"; exit "$1"' "$?" "$status"
または、ダミー/パッドパラメータを追加できます。
sh -c '<< other code >>; [ "$1" != "" ] && exit "$1"; exit "$2"' foo "$?" "$status"
これにより、テストは[ ! -z "$0" ]
(または"$1"
)に変更できます。 zshまたはFishで動作しているかどうかわかりません。私が慣れているすべてのシェルは、解析されるコマンドを評価し、$?
コマンドの引数として渡します。シェルはこれを最後の2つの位置引数に割り当てます。 「別のコード」が完了すると、シェルは値を取得した位置パラメータを調べて空であるかヌルでないことを確認し、適切な位置パラメータ値で終了します。$status
sh -c
sh
$?
環境シェルが終了状態を保存するために$?
またはそれ以外のものを使用している場合、この操作は失敗します。$status
シェルが$?
設定(空でない)を許可している場合、$?
終了状態でない場合や無効な文字シーケンスであっても失敗するため、コマンド全体が構文エラーで拒否されます。
答え2
パールの使用:
perl -e '$a=shift; `<< other code >>`; exit $a' $? # Fails in csh
編集するこれはcshでも機能します(そしてzsh、tcsh、sh、pdksh、ksh93 - Fishでは機能しません)。
perl -e '$a=shift; `<< other code >>`; $a=~s/h// and exit $a; exit shift' "$?h" "$status"