Abstrakt
Um a umzukehren, führen Sie set -x
einfach a aus set +x
. Die meiste Zeit, das Gegenteil einer Zeichenfolge set -str
ist die gleiche Zeichenfolge mit ein +
: set +str
.
Im Allgemeinen können Sie zum Wiederherstellen aller (im Folgenden beschriebenen errexit
) Shell-Optionen (geändert mit dem set
Befehl) Folgendes tun (im Folgenden beschriebene Bash- shopt
Optionen):
oldstate="$(set +o); set -$-" # POSIXly store all set options.
.
.
set -vx; eval "$oldstate" # restore all options stored.
Längere Beschreibung
Bash
Dieser Befehl:
shopt -po xtrace
generiert eine ausführbare Zeichenfolge, die den Status der Option widerspiegelt. Das p
Flag bedeutet Drucken, und das o
Flag gibt an, dass wir nach den vom set
Befehl festgelegten Optionen fragen (im Gegensatz zu den vom shopt
Befehl festgelegten Optionen ). Sie können diese Zeichenfolge einer Variablen zuweisen und die Variable am Ende Ihres Skripts ausführen, um den ursprünglichen Zustand wiederherzustellen.
# 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"
Diese Lösung funktioniert für mehrere Optionen gleichzeitig:
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"
Durch set +vx
das Hinzufügen wird das Drucken einer langen Liste von Optionen vermieden.
Und wenn Sie keine Optionsnamen auflisten,
oldstate="$(shopt -po)"
Es gibt Ihnen die Werte aller Optionen. Wenn Sie die Markierung o
weglassen, können Sie mit den folgenden shopt
Optionen dasselbe tun :
# store state of dotglob option.
dglobstate="$(shopt -p dotglob)"
# store state of all options.
oldstate="$(shopt -p)"
Wenn Sie testen müssen, ob eine set
Option festgelegt ist, ist die idiomatischste Methode (Bash), dies zu tun:
[[ -o xtrace ]]
Das ist besser als die beiden anderen ähnlichen Tests:
[[ $- =~ x ]]
[[ $- == *x* ]]
Bei allen Tests funktioniert Folgendes:
# 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"
So testen Sie den Status einer shopt
Option:
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
Eine einfache, POSIX-kompatible Lösung zum Speichern aller set
Optionen ist:
set +o
was im POSIX-Standard beschrieben wird als:
+ o
Schreiben Sie die aktuellen Optionseinstellungen in die Standardausgabe in einem Format, das für die erneute Eingabe in die Shell als Befehle geeignet ist, mit denen dieselben Optionseinstellungen erzielt werden.
Also einfach:
oldstate=$(set +o)
behält Werte für alle Optionen bei, die mit dem set
Befehl festgelegt wurden.
Um die ursprünglichen Werte der Optionen wiederherzustellen, muss die Variable erneut ausgeführt werden:
set +vx; eval "$oldstate"
Dies entspricht genau der Verwendung von Bashs shopt -po
. Beachten Sie, dass dies nicht alle möglichen Bash- Optionen abdeckt , da einige davon von festgelegt werden shopt
.
bash Sonderfall
Es gibt viele andere Shell-Optionen, die shopt
in bash aufgelistet sind :
$ 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
Diese können an die oben angegebene Variable angehängt und auf die gleiche Weise wiederhergestellt werden:
$ oldstate="$oldstate;$(shopt -p)"
.
. # change options as needed.
.
$ eval "$oldstate"
Es ist möglich (das $-
wird angehängt, um sicherzustellen, dass errexit
es erhalten bleibt):
oldstate="$(shopt -po; shopt -p); set -$-"
set +vx; eval "$oldstate" # use to restore all options.
Hinweis : Jede Shell hat eine etwas andere Methode, um die Liste der gesetzten oder nicht gesetzten Optionen zu erstellen (ganz zu schweigen von den definierten Optionen), sodass die Zeichenfolgen nicht zwischen Shells übertragbar sind, sondern für dieselbe Shell gelten.
zsh Sonderfall
zsh
funktioniert auch korrekt (nach POSIX) seit Version 5.3. In früheren Versionen folgte es POSIX nur teilweise, set +o
indem es Optionen in einem Format druckte, das für die erneute Eingabe in die Shell als Befehle geeignet war, jedoch nur für festgelegte Optionen (es druckte keine nicht festgelegten Optionen).
MKSH Sonderfall
Das mksh (und folglich lksh) ist noch nicht dazu in der Lage (MIRBSD KSH R54 2016/11/11). Das mksh-Handbuch enthält Folgendes:
In einer zukünftigen Version verhält sich set + o POSIX-konform und gibt Befehle aus, um stattdessen die aktuellen Optionen wiederherzustellen.
set -e Spezialfall
In bash wird der Wert von set -e
( errexit
) in Unterschalen zurückgesetzt, was es schwierig macht, seinen Wert set +o
in einer $ (…) -Unterschale zu erfassen .
Um dieses Problem zu umgehen, verwenden Sie:
oldstate="$(set +o); set -$-"
oldstate=$(set +o)
eine einfachere (und POSIX) Möglichkeit ist, alle Optionen zu speichern.pdksh
/mksh
(und anderen pdksh-Derivaten) nicht funktioniert oder beizsh
denenset +o
nur die Abweichungen von den Standardeinstellungen ausgegeben werden. Das würde für Bash / Dash / Yash funktionieren, ist aber nicht portabel.Sie können die
$-
Variable am Anfang lesen , um zu sehen, ob sie-x
gesetzt ist oder nicht, und sie dann in einer Variablen speichern, zAus dem Bash-Handbuch :
quelle
In der Bash wird $ SHELLOPTS mit den Flags gesetzt, die aktiviert sind. Überprüfen Sie dies, bevor Sie xtrace einschalten, und setzen Sie xtrace nur zurück, wenn es zuvor ausgeschaltet war.
quelle
Um nur das Offensichtliche anzugeben, wenn
set -x
es für die Dauer des Skripts gültig sein soll und dies nur eine vorübergehende Testmaßnahme ist (nicht permanent Teil der Ausgabe sein soll), rufen Sie entweder das Skript mit der-x
Option auf, z.... oder ändern Sie vorübergehend das Skript (erste Zeile), um die Debug-Ausgabe zu aktivieren, indem Sie die folgende
-x
Option hinzufügen :Mir ist klar, dass dies wahrscheinlich ein zu breiter Strich für das ist, was Sie wollen, aber es ist der einfachste und schnellste Weg, um das Skript zu aktivieren / deaktivieren, ohne das Skript mit temporären Dingen zu komplizieren, die Sie wahrscheinlich sowieso entfernen möchten (meiner Erfahrung nach).
quelle
Dies bietet Funktionen zum Speichern und Wiederherstellen der Flags, die über den POSIX-
$-
Spezialparameter sichtbar sind . Wir verwenden dielocal
Erweiterung für lokale Variablen. In einem POSIX-konformen portablen Skript werden globale Variablen verwendet (keinlocal
Schlüsselwort):Dies wird ähnlich verwendet, wie Interrupt-Flags im Linux-Kernel gespeichert und wiederhergestellt werden:
Dies funktioniert nicht für die erweiterten Optionen, die nicht in der
$-
Variablen enthalten sind.Ich habe gerade bemerkt, dass POSIX das hat, wonach ich gesucht habe: Das
+o
Argument vonset
ist keine Option, sondern ein Befehl, der eine Reihe von Befehleneval
ausgibt, die, wenn -ed, die Optionen wiederherstellen. Damit:Das ist es.
Ein kleines Problem ist, dass, wenn die
-x
Option vorhereval
aktiviert wird, eine hässliche Flut vonset -o
Befehlen zu sehen ist. Um dies zu beseitigen, können wir Folgendes tun:quelle
Sie können eine Unterschale verwenden.
quelle