Astratto
Per invertire a set -x
basta eseguire a set +x
. La maggior parte del tempo, il contrario di una stringa set -str
è la stessa stringa con un +
: set +str
.
In generale, per ripristinare tutte errexit
le opzioni di shell (leggi di seguito su bash ) (modificate con il set
comando) potresti fare (leggi anche di seguito sulle shopt
opzioni di bash ):
oldstate="$(set +o); set -$-" # POSIXly store all set options.
.
.
set -vx; eval "$oldstate" # restore all options stored.
Descrizione più lunga
bash
Questo comando:
shopt -po xtrace
genererà una stringa eseguibile che riflette lo stato dell'opzione. La p
bandiera significa stampa e la o
bandiera specifica che stiamo chiedendo delle opzioni impostate dal set
comando (al contrario delle opzioni impostate dal shopt
comando). È possibile assegnare questa stringa a una variabile ed eseguire la variabile alla fine dello script per ripristinare lo stato iniziale.
# 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"
Questa soluzione funziona contemporaneamente per più opzioni:
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"
L'aggiunta set +vx
evita la stampa di un lungo elenco di opzioni.
E, se non elenchi alcun nome di opzione,
oldstate="$(shopt -po)"
ti dà i valori di tutte le opzioni. E, se lasci la o
bandiera, puoi fare le stesse cose con le shopt
opzioni:
# store state of dotglob option.
dglobstate="$(shopt -p dotglob)"
# store state of all options.
oldstate="$(shopt -p)"
Se devi verificare se set
un'opzione è impostata, il modo più idiomatico (Bash) per farlo è:
[[ -o xtrace ]]
che è meglio degli altri due test simili:
[[ $- =~ x ]]
[[ $- == *x* ]]
Con uno qualsiasi dei test, questo funziona:
# 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"
Ecco come testare lo stato di shopt
un'opzione:
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
Una soluzione semplice, conforme a POSIX per memorizzare tutte le set
opzioni è:
set +o
che è descritto nello standard POSIX come:
+ o
Scrivi le impostazioni correnti delle opzioni nell'output standard in un formato adatto per il ripristino nella shell come comandi che ottengono le stesse impostazioni delle opzioni.
Quindi, semplicemente:
oldstate=$(set +o)
conserverà i valori per tutte le opzioni impostate usando il set
comando.
Ancora una volta, ripristinare le opzioni ai loro valori originali è una questione di esecuzione della variabile:
set +vx; eval "$oldstate"
Questo è esattamente equivalente all'utilizzo di Bash shopt -po
. Nota che non coprirà tutte le possibili opzioni di Bash , poiché alcune di queste sono impostate da shopt
.
bash caso speciale
Ci sono molte altre opzioni di shell elencate con shopt
in 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
Questi potrebbero essere aggiunti alla variabile impostata sopra e ripristinati allo stesso modo:
$ oldstate="$oldstate;$(shopt -p)"
.
. # change options as needed.
.
$ eval "$oldstate"
È possibile fare ( $-
è allegato per garantire che errexit
sia preservato):
oldstate="$(shopt -po; shopt -p); set -$-"
set +vx; eval "$oldstate" # use to restore all options.
Nota : ogni shell ha un modo leggermente diverso di creare un elenco di opzioni impostate o non impostate (per non parlare delle diverse opzioni definite), quindi le stringhe non sono portatili tra le shell, ma sono valide per la stessa shell.
caso speciale zsh
zsh
funziona anche correttamente (seguendo POSIX) dalla versione 5.3. Nelle versioni precedenti seguiva POSIX solo parzialmente set +o
in quanto stampava le opzioni in un formato che era adatto per essere reintegrato nella shell come comandi, ma solo per le opzioni impostate (non stampava opzioni non impostate ).
caso speciale mksh
Il mksh (e di conseguenza lksh) non è ancora (MIRBSD KSH R54 2016/11/11) in grado di farlo. Il manuale di mksh contiene questo:
In una versione futura, set + o si comporterà con POSIX e stampa i comandi per ripristinare invece le opzioni correnti.
set -e caso speciale
In bash, il valore di set -e
( errexit
) viene resettato all'interno di sotto-shell, il che rende difficile catturarne il valore con set +o
all'interno di una sotto-shell $ (...).
Per ovviare al problema, utilizzare:
oldstate="$(set +o); set -$-"