Resumo
Para reverter um set -x
, basta executar um set +x
. Na maioria das vezes, o contrário de uma string set -str
é a mesma string com um +
: set +str
.
Em geral, para restaurar todas as opções de shell (leia abaixo sobre o bash errexit
) (alteradas com o comando set
) você pode fazer (também leia abaixo sobre bash shopt
options):
oldstate="$(set +o); set -$-" # POSIXly store all set options.
.
.
set -vx; eval "$oldstate" # restore all options stored.
Descrição mais longa
bash
Este comando:
shopt -po xtrace
irá gerar uma string executável que reflete o estado da opção.
O sinalizador p
significa print e o sinal o
especifica que estamos perguntando sobre as opções configuradas pelo comando set
(em oposição às opções configuradas pelo comando shopt
).
Você pode atribuir essa string a uma variável e executar a variável no final do seu script para restaurar o estado inicial.
# 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"
Esta solução funciona para várias opções simultaneamente:
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"
Adicionar set +vx
evita a impressão de uma longa lista de opções.
E, se você não listar nenhum nome de opção,
oldstate="$(shopt -po)"
fornece os valores de todas as opções.
E, se você deixar de fora a bandeira o
,
você pode fazer as mesmas coisas com shopt
options:
# store state of dotglob option.
dglobstate="$(shopt -p dotglob)"
# store state of all options.
oldstate="$(shopt -p)"
Se você precisar testar se uma opção set
está definida,
a maneira mais idiomática (Bash) de fazer isso é:
[[ -o xtrace ]]
que é melhor que os outros dois testes semelhantes:
-
[[ $- =~ x ]]
-
[[ $- == *x* ]]
Com qualquer um dos testes, isso funciona:
# 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"
Veja como testar o estado de uma opção 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
Uma solução simples e compatível com POSIX para armazenar todas as opções set
é:
set +o
que é descrito no padrão POSIX como:
+o
Write the current option settings to standard output in a format that is suitable for reinput to the shell as commands that achieve the same options settings.
Então, simplesmente:
oldstate=$(set +o)
preservará os valores de todas as opções definidas usando o comando set
.
Novamente, restaurar as opções para seus valores originais é uma questão de executar a variável:
set +vx; eval "$oldstate"
Isso equivale exatamente ao uso do shopt -po
do Bash. Note que não cobrirá todas possíveis Bash opções, já que algumas delas são definidas por shopt
.
caso especial de bash
Existem muitas outras opções de shell listadas com shopt
no 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
Eles podem ser anexados à variável definida acima e restaurados da mesma maneira:
$ oldstate="$oldstate;$(shopt -p)"
.
. # change options as needed.
.
$ eval "$oldstate"
É possível fazer (o $-
é anexado para garantir que errexit
seja preservado):
oldstate="$(shopt -po; shopt -p); set -$-"
set +vx; eval "$oldstate" # use to restore all options.
Nota : cada shell tem uma maneira ligeiramente diferente de criar a lista de opções definidas ou não definidas (para não mencionar as diferentes opções definidas), portanto, as strings não são portáveis entre os shells, mas são válidos para o mesmo shell.
caso especial zsh
zsh
também funciona corretamente (seguindo o POSIX) desde a versão 5.3. Nas versões anteriores, ele seguia o POSIX apenas parcialmente com set +o
em que ele imprimia as opções em um formato adequado para reinputá-las como comandos, mas apenas para as opções set (não foi impresso < em> un-set opções).
caso especial mksh
O mksh (e por conseqüência lksh) ainda não é capaz (MIRBSD KSH R54 2016/11/11) de fazer isso. O manual do mksh contém isto:
In a future version, set +o will behave POSIX compliant and print commands to restore the current options instead.
set -e caso especial
No bash, o valor de set -e
( errexit
) é reconfigurado dentro de sub-shells, o que torna difícil capturar seu valor com set +o
dentro de um sub-shell $ (…).
Como solução alternativa, use:
oldstate="$(set +o); set -$-"