シェルオプションを修正して復元する方法に関するさまざまなスタック交換サイトとUnixヘルプフォーラムで多くの質問を読んだ。ここで見つけた最も包括的な質問は次のとおりです。`set -x`を「元に戻す」方法は?
これ知恵を得る以前の設定を保存して後で復元した結果set +o
のようです。shopt -po
eval
ただし、bash 3.xおよび4.xを使用したセルフテストでは、errexit
コマンド置換を実行したときにオプションが正しく保存されませんでした。
以下は、問題を示すサンプルスクリプトです。
set -o errexit
set -o nounset
echo "LOCAL SETTINGS:"
set +o
OLDOPTS=$(set +o)
echo
echo "SAVED SETTINGS:"
echo "$OLDOPTS"
と出力(無関係な変数をいくつか削除しました):
LOCAL SETTINGS:
set -o errexit
set -o nounset
SAVED SETTINGS:
set +o errexit
set -o nounset
これは非常に危険に見えます。私が書くほとんどのスクリプトは、errexit
コマンドが失敗した場合に実行を停止することに依存しています。私は私のスクリプトの1つでこれによって発生したバグを見つけました。最終的に復元しなければならなかった関数がerrexit
それを上書きし、再びデフォルトに設定されました。去るスクリプトの進行中。
私がやりたいことは、必要に応じてオプションを設定してから復元できる関数を書くことです。みんな終了する前にオプションを正しく選択してください。しかし、コマンド置換によって呼び出されるサブシェルではerrexit
継承できないようです。
set +o
コマンド置換を使用したり、FIFOリングをジャンプしたりせずに結果を保存する方法がわかりません。読み取ることはできますが、書き込めない、または$SHELLOPTS
使用できない形式ですeval
。
別の方法は、次のものを使用することです。サブシェル機能しかし、これは出力を記録し、複数の変数を返すのに多くの問題を引き起こします。
おそらく関連があるでしょう:https://stackoverflow.com/questions/29532904/bash-subshell-errexit-semantics(bash 4.4以降の解決策があるようですが、ポータブルソリューションを好む)
ベストアンサー1
あなたがやっていることはうまくいくでしょう。ただし、 bash はコマンド置換でそのオプションをオフにするので、errexit
そのオプションを除くすべてを保持します。これはbashによって異なり、errexit
オプションによって異なります。 Bash はerrexit
POSIX モードで実行しても保持されます。 bash 4.4以降、bashはerrexit
コマンド置換で有効かどうかを消去しませんshopt -s inherit_errexit
。
このオプションは、コマンド置換内でコードが実行される前にオフになるため、外部で確認する必要があります。
OLDOPTS=$(set +o)
case $- in
*e*) OLDOPTS="$OLDOPTS; set -e";;
*) OLDOPTS="$OLDOPTS; set +e";;
esac
これらの複雑さが気に入らない場合は、代わりにzshを使用してください。
setopt local_options