抽象的な

抽象的な

set -xランダムに設定するよりも、スクリプトの先頭で「元に戻す」(設定前の状態に戻る)したいと思います+x。これは可能ですか?

PS:確認しましたここ;私が知っている限り、これは私の質問に対する答えではないようです。

ベストアンサー1

抽象的な

を元に戻すset -x場合set +x。ほとんどの場合、文字列の反対は:と同じ文字列set -strです。+set +str

通常、すべてのerrexitシェルオプション(bashについては以下を参照)を復元するには(コマンドを使用して変更されますset)、次のことができます(bashshoptオプションについても以下を参照)。

oldstate="$(set +o)"                # POSIXly store all set options.
.
.
set -vx; eval "$oldstate"         # restore all options stored.

十分ですが、bashにはset(or)と一部を介してshopt -poアクセスされる2つのオプションセットがあります。また、bashはshopt -pサブシェルに入ってもset -e持続しません。拡張によって生成されたオプションのリストは、$-シェルに再入力されない可能性があります。

bash で現在の状態全体をキャプチャするには、次のようにします。

oldstate="$(shopt -po; shopt -p)"; [[ -o errexit ]] && oldstate="$oldstate; set -e"

inherit_errexitまたは、フラグ設定が気に入らない場合(そしてbashは≥4.4です):

shopt -s inherit_errexit;    oldstate="$(shopt -po; shopt -p)"

より長い説明

強く打つ

このコマンドは次のとおりです。

shopt -po xtrace

オプションの状態を反映する実行可能な文字列を生成するために使用されます。フラグはp印刷を意味し、フラグはコマンドによって設定されたオプション(オプションセットではない)oについて尋ねることを指定します。setただコマンドを介してshopt)。この文字列を変数に割り当て、スクリプトの最後で実行して初期状態を復元できます。

# store state of xtrace option.
tracestate="$(shopt -po xtrace)"

# change xtrace as needed
echo "some commands with xtrace as externally selected"
set -x
echo "some commands with xtrace set"

# restore the value of xtrace to its original value.
eval "$tracestate"

このソリューションは複数のオプションと同時に動作します。

oldstate="$(shopt -po xtrace noglob errexit)"

# change options as needed
set -x
set +x
set -f
set -e
set -x

# restore to recorded state:
set +vx; eval "$oldstate"

set +vx長いオプションのリストを印刷しないように追加されました。


オプション名をリストしない場合

oldstate="$(shopt -po)"

すべての(設定)オプションの値を提供します。フラグを省略すると、オプションを使用して同じ操作を実行oできます。shopt

# store state of dotglob option.
dglobstate="$(shopt -p dotglob)"

# store state of all options.
oldstate="$(shopt -p)"

オプションが設定されていることをテストする必要がある場合、set最も慣用的な方法は次のとおりです。

[[ -o xtrace ]]

これは他の2つの同様のテストよりも優れています。

  1. [[ $- =~ x ]]
  2. [[ $- == *x* ]]

すべてのテストで次のように動作します。

# record the state of the xtrace option in ts (tracestate):
[ -o xtrace ] && ts='set -x' || ts='set +x'

# change xtrace as needed
echo "some commands with xtrace as externally selected"
set -x
echo "some commands with xtrace set"

# set the xtrace option back to what it was.
eval "$ts"

オプションの状態をテストする方法は次のとおりですshopt

if shopt -q dotglob
then
        # dotglob is set, so “echo .* *” would list the dot files twice.
        echo *
else
        # dotglob is not set.  Warning: the below will list “.” and “..”.
        echo .* *
fi

POSIX

すべてのオプションを保存するための簡単なPOSIX互換ソリューションはset次のとおりです。

set +o

これはPOSIX規格に記載されているように:

+o

    同じオプション設定を実装するコマンドでシェルに再入力するのに適した形式で、現在のオプション設定を標準出力に書き込みます。

簡単に言えば、

oldstate=$(set +o)

setこのコマンドで設定されたすべてのオプションの値は(一部のシェルでは)保持されます。

同様に、オプションを元の値に復元することは、単に変数を実行する問題です。

set +vx; eval "$oldstate"

これはBashを使用するのと同じですshopt -poいいえ書くみんな可能吹くオプションの一部のみが提供されるためですshopt

バッシュ特別な場合

shoptBashには他の多くのシェルオプションがリストされています。

$ shopt
autocd          off
cdable_vars     off
cdspell         off
checkhash       off
checkjobs       off
checkwinsize    on
cmdhist         on
compat31        off
compat32        off
compat40        off
compat41        off
compat42        off
compat43        off
complete_fullquote  on
direxpand       off
dirspell        off
dotglob         off
execfail        off
expand_aliases  on
extdebug        off
extglob         off
extquote        on
failglob        off
force_fignore   on
globasciiranges off
globstar        on
gnu_errfmt      off
histappend      on
histreedit      off
histverify      on
hostcomplete    on
huponexit       off
inherit_errexit off
interactive_comments    on
lastpipe        on
lithist         off
login_shell     off
mailwarn        off
no_empty_cmd_completion off
nocaseglob      off
nocasematch     off
nullglob        off
progcomp        on
promptvars      on
restricted_shell    off
shift_verbose   off
sourcepath      on
xpg_echo        off

これは上記の変数に追加され、同じ方法で復元できます。

$ oldstate="$oldstate;$(shopt -p)"
.
.                                   # change options as needed.
.
$ eval "$oldstate" 

バッシュのset -e特別なケース

set -eBashでは、()の値がerrexitサブシェル内でリセットされるため、set +o$(...)サブシェル内でその値を取得することは困難です。

回避策として、次を使用します。

oldstate="$(set +o)"; [[ -o errexit ]] && oldstate="$oldstate; set -e"

または(ターゲットと競合せずにbashがそれをサポートしている場合)、このinherit_errexitオプションを使用できます。


ノート:各シェルは設定または設定解除オプションのリストを少し異なって作成します(他のオプションが定義されていることは言うまでもありません)、文字列はシェル間で移植可能ではありませんが、同じシェルでは有効です。

zsh特別なケース

zshまた、バージョン5.3(POSIX互換)からもうまく機能します。以前のバージョンでは、set +oシェルにコマンドで再入力するのに適した形式でオプションを印刷するという点で、POSIXに部分的に従いました。置くオプション(印刷されません。未設定オプション)。

mksh特別なケース

mksh(および結果lksh)はまだこれを実行できません(MIRBSD KSH R54 2016/11/11)。 mksh マニュアルには次の内容が含まれています。

今後のリリースでは、set +oがPOSIX仕様で動作し、現在のオプションを復元するコマンドを印刷します。

おすすめ記事