errexitを含むすべてのシェルオプションを保存および復元する方法

errexitを含むすべてのシェルオプションを保存および復元する方法

シェルオプションを修正して復元する方法に関するさまざまなスタック交換サイトとUnixヘルプフォーラムで多くの質問を読んだ。ここで見つけた最も包括的な質問は次のとおりです。`set -x`を「元に戻す」方法は?

これ知恵を得る以前の設定を保存して後で復元した結果set +oのようです。shopt -poeval

ただし、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-subshel​​l-errexit-semantics(bash 4.4以降の解決策があるようですが、ポータブルソリューションを好む)

ベストアンサー1

あなたがやっていることはうまくいくでしょう。ただし、 bash はコマンド置換でそのオプションをオフにするので、errexitそのオプションを除くすべてを保持します。これはbashによって異なり、errexitオプションによって異なります。 Bash はerrexitPOSIX モードで実行しても保持されます。 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

おすすめ記事