Чтобы отменить 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
указывает, что мы спрашиваем об опциях, установленных командой 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 ]]
что лучше, чем два других аналогичных теста:
{{1} }
[[$ - = ~ 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
Простой, POSIX -совместимое решение для хранения всех параметров набора
:
set +o
, который описан в стандарте POSIX как:
+ o
Записать текущие настройки параметров в стандартный вывод в формате , который подходит для повторного ввода в оболочку в качестве команд, которые достигают тех же настроек параметров.
Итак, просто:
oldstate=$(set +o)
сохранит значения для всех параметров, установленных с помощью команды set
.
Опять же, восстановление параметров до их исходных значений - это вопрос выполнения переменной:
set +vx; eval "$oldstate"
Это в точности эквивалентно использованию Bash shopt -po
. Обратите внимание, что он не охватывает все возможные Bash параметры, поскольку некоторые из них устанавливаются shopt
.
Есть много других параметров оболочки, перечисленных в shopt
в bash:
$ 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
также работает правильно (в соответствии с POSIX), начиная с версии 5.3. В предыдущих версиях он следовал POSIX лишь частично с set + o
в том смысле, что он печатал параметры в формате, подходящем для повторного ввода в оболочку в виде команд, но только для set options (it не печатал снятые параметры).
mksh (и, как следствие, lksh) еще не может (MIRBSD KSH R54 2016/11/11) сделать это. В руководстве по mksh содержится следующее:
В будущей версии set + o будет вести себя в соответствии с POSIX, а команды печати вместо этого будут восстанавливать текущие параметры.
В bash значение set -e
( errexit
) сбрасывается внутри суб-оболочки, что затрудняет захват его значения. с set + o
внутри суб-оболочки $ (…).
В качестве временного решения используйте:
oldstate="$(set +o); set -$-"