回答:
を逆にするには、set -x単にを実行しset +xます。ほとんどの場合、文字列の逆は:をset -str持つ同じ文字列+ですset +str。
一般に、すべての(bashについて以下で読むerrexit)シェルオプション(setコマンドで変更)を復元するには、以下を実行できます(bash shoptオプションについても以下をお読みください):
oldstate="$(set +o); set -$-" # POSIXly store all set options.
.
.
set -vx; eval "$oldstate" # restore all options stored.
このコマンド:
shopt -po xtrace
オプションの状態を反映する実行可能文字列を生成します。pフラグ手段が印刷して、o我々はオプションで(S)セットについて尋ねていることをフラグが指定する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オプションが設定されているかどうかをテストする必要がある場合、最も一般的な(Bash)方法は次のとおりです。
[[ -o xtrace ]]
これは、他の2つの同様のテストよりも優れています。
[[ $- =~ x ]][[ $- == *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
すべてのsetオプションを保存する単純なPOSIX準拠のソリューションは次のとおりです。
set +o
+ o
現在のオプション設定を、同じオプション設定を実現するコマンドとしてシェルに再入力するのに適した形式で標準出力に書き込みます。
だから、単純に:
oldstate=$(set +o)
setコマンドを使用して設定されたすべてのオプションの値を保持します。
繰り返しますが、オプションを元の値に復元するには、変数を実行します。
set +vx; eval "$oldstate"
これは、Bashの使用とまったく同じshopt -poです。これらの一部はによって設定されるため、可能なすべてのBashオプションを網羅しているわけではないことに注意してください。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"
実行することが可能です(保持$-するために追加errexitされます):
oldstate="$(shopt -po; shopt -p); set -$-"
set +vx; eval "$oldstate" # use to restore all options.
注:各シェルには、設定または設定解除されるオプションのリストを作成するためのわずかに異なる方法があります(定義されているさまざまなオプションは言うまでもありません)。したがって、文字列はシェル間で移植できませんが、同じシェルに対して有効です。
zshバージョン5.3以降も(POSIXに準拠して)正しく動作します。以前のバージョンではset +o、コマンドとしてシェルに再入力するのに適した形式でオプションを印刷しましたが、設定オプションのみでオプションを印刷するという点で、POSIXに部分的にのみ従いました(未設定オプションは印刷しませんでした)。
mksh(および結果としてlksh)はまだこれを行うことができません(MIRBSD KSH R54 2016/11/11)。mkshマニュアルにはこれが含まれています。
将来のバージョンでは、set + oはPOSIX準拠で動作し、代わりに現在のオプションを復元するコマンドを出力します。
bashでは、set -e(errexit)の値はサブシェル内でリセットされるためset +o、$(…)サブシェル内で値をキャプチャすることは困難です。
回避策として、次を使用します。
oldstate="$(set +o); set -$-"
Almquistシェルと派生物(少なくともdashNetBSD / FreeBSD sh)および bash4.4以上を使用すると、オプションを関数に対してローカルにすることができますlocal -(必要に$-応じて変数をローカルにします)。
$ bash-4.4 -c 'f() { local -; set -x; echo test; }; f; echo no trace'
+ echo test
test
no trace
これはソースファイルには適用されませんが、その回避策sourceとして再定義できますsource() { . "$@"; }。
ではksh88、オプションの変更はデフォルトで関数に対してローカルです。でksh93、それはfunction f { ...; }構文で定義された関数の場合のみです(そしてスコープはksh88を含む他のシェルで使用される動的スコープと比較して静的です):
$ ksh93 -c 'function f { set -x; echo test; }; f; echo no trace'
+ echo test
test
no trace
ではzsh、localoptionsオプションを使用してこれを行います。
$ zsh -c 'f() { set -o localoptions; set -x; echo test; }; f; echo no trace'
+f:0> echo test
test
no trace
POSIXly、次のことができます:
case $- in
(*x*) restore=;;
(*) restore='set +x'; set -x
esac
echo test
{ eval "$restore";} 2> /dev/null
echo no trace
ただし、一部のシェルは+ 2> /dev/null復元時にaを出力します(既に有効になっている場合は、もちろんその構成のトレースが表示されます)。また、このアプローチはリエントラントではありません(自分自身を呼び出す関数または同じトリックを使用する別の関数で行う場合など)。caseset -x
それを回避するスタックを実装する方法については、https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh(POSIXシェルの変数とオプションのローカルスコープ)を参照してください。
任意のシェルで、サブシェルを使用してオプションの範囲を制限できます
$ sh -c 'f() (set -x; echo test); f; echo no trace'
+ echo test
test
no trace
ただし、これはオプションだけでなく、すべて(変数、関数、エイリアス、リダイレクト、現在の作業ディレクトリなど)の範囲を制限します。
oldstate=$(set +o)は、すべてのオプションを保存するより簡単な(そしてPOSIX)方法であるように思えます。
pdksh/ mksh(及び他のpdkshの誘導体)又はzsh場合set +oのみ、デフォルト設定からの偏差を出力します。これはbash / dash / yashで機能しますが、移植性はありません。
$-最初に変数を読み取り、-x設定されているかどうかを確認してから、変数に保存できます。
if [[ $- == *x* ]]; then
was_x_set=1
else
was_x_set=0
fi
Bashマニュアルから:
($-、ハイフン)呼び出し、set builtinコマンドによる指定、またはシェル自体(-iオプションなど)による設定で指定された現在のオプションフラグに展開します。
[[ $SHELLOPTS =~ xtrace ]] && wasset=1
set -x
echo rest of your script
[[ $wasset -eq 0 ]] && set +x
bashでは、$ SHELLOPTSはオンになっているフラグで設定されます。xtraceをオンにする前に確認し、以前にオフであった場合にのみxtraceをリセットします。
明らかなことを述べるset -xために、スクリプトの期間中に有効であり、これが単なる一時的なテスト手段(永続的に出力の一部ではない)である-x場合は、オプション付きのスクリプトを呼び出します。
$ bash -x path_to_script.sh
...または、スクリプト(最初の行)を一時的に変更して、-xオプションを追加してデバッグ出力を有効にします。
#!/bin/bash -x
...rest of script...
私はこれがおそらくあなたが望むものに対して広すぎるストロークであることを理解していますが、それはおそらく(私の経験では)おそらく削除したい一時的なものでスクリプトを過度に複雑にすることなく、有効化/無効化する最も簡単で迅速な方法です。
これは、POSIX $-特殊パラメーターを介して表示されるフラグを保存および復元する機能を提供します。localローカル変数に拡張機能を使用します。POSIX準拠のポータブルスクリプトでは、グローバル変数が使用されます(localキーワードなし)。
save_opts()
{
echo $-
}
restore_opts()
{
local saved=$1
local on
local off=$-
while [ ${#saved} -gt 0 ] ; do
local rest=${saved#?}
local first=${saved%$rest}
if echo $off | grep -q $first ; then
off=$(echo $off | tr -d $first)
fi
on="$on$first"
saved=$rest
done
set ${on+"-$on"} ${off+"+$off"}
}
これは、Linuxカーネルで割り込みフラグが保存および復元される方法と同様に使用されます。
Shell: Kernel:
flags=$(save_opts) long flags;
save_flags (flags);
set -x # or any other local_irq_disable(); /* disable irqs on this core */
# ... -x enabled ... /* ... interrupts disabled ... */
restore_opts $flags restore_flags(flags);
# ... x restored ... /* ... interrupts restored ... */
これは、$-変数に含まれていない拡張オプションでは機能しません。
POSIXが私が探していたものを持っていることに気付きました:の+o引数はsetオプションではなく、eval-edがオプションを復元するコマンドの束をダンプするコマンドです。そう:
flags=$(set +o)
set -x
# ...
eval "$flags"
それでおしまい。
1つの小さな問題は、-xこれより前にオプションをオンにするとeval、set -oコマンドのい突風が見られることです。これを排除するために、次のことができます。
set +x # turn off trace not to see the flurry of set -o.
eval "$flags" # restore flags
サブシェルを使用できます。
(
set …
do stuff
)
Other stuff, that set does not apply to