Frage

Wenn ich will, für das Null-Zeichenfolge überprüfen, die ich tun würde

[ -z $mystr ]

aber was, wenn ich, ob die Variable überprüfen möchten hat überhaupt definiert? Oder gibt es keinen Unterschied in der Bash Scripting?

War es hilfreich?

Lösung

Ich denke, die Antwort, die Sie nach sind impliziert (wenn nicht angegeben) von Vinko 's beantworten , obwohl es einfach nicht ausgeschrieben ist. Zur Unterscheidung, ob VAR eingestellt ist, aber leer oder nicht gesetzt ist, können Sie:

if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi

Sie können sich wahrscheinlich die beiden Tests in der zweiten Zeile kombinieren in einem mit:

if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi

Wenn Sie jedoch in der Dokumentation zu Autoconf lesen, werden Sie feststellen, dass sie nicht empfohlen Begriffe mit ‚-a‘ und empfehlen die Kombination mit separaten einfachen Tests kombiniert mit &&. Ich habe kein System angetroffen, wo es ein Problem gibt; das bedeutet nicht, haben sie nicht zu existieren verwendet (aber sie sind wahrscheinlich extrem selten in diesen Tagen, auch wenn sie in der fernen Vergangenheit nicht so selten waren).

Sie können die Details von diesen finden, und anderen damit zusammenhängenden Shell-Parameter Erweiterungen , die test oder [ Befehl und bedingte Ausdrücke in der Bash Handbuch.


wurde ich kürzlich per E-Mail über diese Antwort mit der Frage gestellt:

  

Mit zwei Tests, und ich verstehe die zweiten gut, aber nicht die erste. Genauer gesagt verstehe ich nicht die Notwendigkeit für variable Erweiterung

if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
     

Wäre das nicht das gleiche erreichen?

if [ -z "${VAR}" ]; then echo VAR is not set at all; fi

Messe Frage -. Die Antwort ‚Nein, Ihre einfachere Alternative tut nicht das Gleiche‘

Angenommen, ich schreibe dies vor Ihrem Test:

VAR=

Ihr Test wird sagen: „VAR ist nicht gesetzt“, aber ich wird (implizit, weil es nichts Echo) sagen „VAR ist gesetzt, aber sein Wert kann leer sein“. Versuchen Sie dieses Skript:

(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo JL:1 VAR is not set at all; fi
if [ -z "${VAR}" ];     then echo MP:1 VAR is not set at all; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo JL:2 VAR is not set at all; fi
if [ -z "${VAR}" ];     then echo MP:2 VAR is not set at all; fi
)

Die Ausgabe lautet:

JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all

In dem zweiten Paar von Tests wird die Variable gesetzt, aber es wird auf den leeren Wert gesetzt. Dies ist der Unterschied, dass die ${VAR=value} und ${VAR:=value} Notationen machen. Das Gleiche gilt für ${VAR-value} und ${VAR:-value} und ${VAR+value} und ${VAR:+value}, und so weiter.


Wie Gili weist in seinem Antwort , wenn Sie bash mit der set -o nounset Option ausführen, dann scheitert die grundlegende Antwort oben mit unbound variable. Es ist leicht zu lösen:

if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi

Oder Sie könnten die set -o nounset Option mit set +u (set -u äquivalent zu set -o nounset).

Abbrechen

Andere Tipps

~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO=""
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO="a"
~> if [ -z $FOO ]; then echo "EMPTY"; fi
~> 

-z arbeitet für zu undefinierten Variablen. Zur Unterscheidung zwischen einem undefinierten und eineineeines definieren Sie die Dinge aufgelistet hier oder mit klaren Erklärungen , hier .

sauberste Weg ist mit Expansion wie in diesen Beispielen. Um alle Optionen die Parameter Expansion Abschnitt des Handbuchs überprüfen.

Alternate Wort:

~$ unset FOO
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
~$ FOO=""
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
DEFINED

Standardwert:

~$ FOO=""
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
~$ unset FOO
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
UNDEFINED

Natürlich kann man eine dieser anders verwenden würde, setzen Sie den Wert anstelle von ‚Standardwert‘ wollen und die Erweiterung direkt mit gegebenenfalls.

Erweiterte Bash Scripting Guide, 10.2. Parameter Substitution:

  • $ {var + blahblah}: wenn var definiert ist, 'blahblah' ist für die substituierte Ausdruck, sonst null wird ersetzt
  • $ {var-blahblah}: wenn var definiert ist, wird es selbst ersetzt, sonst 'Blahblah' wird ersetzt
  • $ {? Var blahblah}: wenn var definiert ist, es substituiert ist, sonst die Funktion existiert mit ‚blahblah‘ als Fehlermeldung.


Ihre Programmlogik auf der Basis, ob die Variable $ mystr definiert ist oder nicht, können Sie wie folgt vor:

isdefined=0
${mystr+ export isdefined=1}

jetzt, wenn isdefined = 0, dann wird die Variable nicht definiert wurde, wenn isdefined = 1 die Variable definiert wurde

Auf diese Weise Variablen zu prüfen ist besser als die oben genannte Antwort, weil es eleganter, lesbar ist, und wenn Ihr Bash-Shell auf Fehler auf der Verwendung von nicht definierten Variablen (set -u) konfiguriert wurde, wird das Skript vorzeitig beenden.


Weitere nützliche Sachen:

einen Standardwert von 7 bis mystr $ zugewiesen haben, wenn es nicht definiert ist, und lassen Sie es intakt anders:

mystr=${mystr- 7}

eine Fehlermeldung zu drucken und die Funktion zu beenden, wenn die Variable ist nicht definiert:

: ${mystr? not defined}

Beachten Sie, dass ich hier gebraucht ‚:‘., Um nicht den Inhalt von $ mystr als Befehl für den Fall ausgeführt, um es definiert wird

Eine Zusammenfassung der Tests.

[ -n "$var" ] && echo "var is set and not empty"
[ -z "$var" ] && echo "var is unset or empty"
[ "${var+x}" = "x" ] && echo "var is set"  # may or may not be empty
[ -n "${var+x}" ] && echo "var is set"  # may or may not be empty
[ -z "${var+x}" ] && echo "var is unset"
[ -z "${var-x}" ] && echo "var is set and empty"

https://stackoverflow.com/a/9824943/14731 enthält eine bessere Antwort (eine, die besser lesbar und arbeitet mit set -o nounset aktiviert). Es funktioniert in etwa wie folgt aus:

if [ -n "${VAR-}" ]; then
    echo "VAR is set and is not empty"
elif [ "${VAR+DEFINED_BUT_EMPTY}" = "DEFINED_BUT_EMPTY" ]; then
    echo "VAR is set, but empty"
else
    echo "VAR is not set"
fi

Der explizite Weg für eine Variable, um zu überprüfen wäre definiert:

[ -v mystr ]

eine weitere Option: der "Liste Array-Indizes" Expansion :

$ unset foo
$ foo=
$ echo ${!foo[*]}
0
$ foo=bar
$ echo ${!foo[*]}
0
$ foo=(bar baz)
$ echo ${!foo[*]}
0 1

das einzige Mal, das auf die leere Zeichenfolge erweitert ist, wenn foo nicht gesetzt ist, so dass Sie es mit der Zeichenfolge bedingte überprüfen:

$ unset foo
$ [[ ${!foo[*]} ]]; echo $?
1
$ foo=
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=bar
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=(bar baz)
$ [[ ${!foo[*]} ]]; echo $?
0

sollte in jeder bash Version> = 3.0

nicht dieses Fahrrad zu vergießen noch weiter, wollte aber hinzufügen

shopt -s -o nounset

etwas, das Sie an die Spitze eines Skripts hinzufügen könnte, die Fehler, wenn Variablen nicht erklärt irgendwo im Script. Die Nachricht, die Sie sehen würden, ist unbound variable, aber wie andere erwähnen es wird nicht einen leeren String oder Null-Wert fangen. Um sicherzustellen, dass jeder einzelne Wert nicht leer ist, können wir eine Variable testen, wie es mit ${mystr:?} erweitert ist, die auch als Dollarzeichen Expansion bekannt, die mit parameter null or not set Fehler würde.

Das Handbuch Bash Reference ist eine maßgebliche Quelle für Informationen über bash.

Hier ist ein Beispiel für eine Variable zu testen, um zu sehen, ob es vorhanden ist:

if [ -z "$PS1" ]; then
        echo This shell is not interactive
else
        echo This shell is interactive
fi

(von Abschnitt 6.3.2 .)

Hinweis

, dass das Leerzeichen nach dem offenen [ und vor dem ] ist nicht optional .


Tipps für Vim-Benutzer

Ich hatte ein Skript, das mehrere Erklärungen hatte, wie folgt:

export VARIABLE_NAME="$SOME_OTHER_VARIABLE/path-part"

Aber ich wollte, dass sie auf alle vorhandenen Werte verschieben. Also habe ich wieder schrieb sie wie folgt aussehen:

if [ -z "$VARIABLE_NAME" ]; then
        export VARIABLE_NAME="$SOME_OTHER_VARIABLE/path-part"
fi

Ich konnte dies in vim automatisieren eine schnelle Regex:

s/\vexport ([A-Z_]+)\=("[^"]+")\n/if [ -z "$\1" ]; then\r  export \1=\2\rfi\r/gc

Dies kann durch Auswahl der entsprechenden Linien visuell angewandt wird, dann : eingeben. Die Befehlsleiste vorge auffüllt mit :'<,'>. Fügen Sie den obigen Befehl und drücken Sie Enter.


auf dieser Version von Vim Getestete:

VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Aug 22 2015 15:38:58)
Compiled by root@apple.com

Windows-Benutzer verschiedene Zeilenende mögen.

Hier ist, was ich denke, ein viel klarer Weg, um zu überprüfen, ob eine Variable definiert ist:

var_defined() {
    local var_name=$1
    set | grep "^${var_name}=" 1>/dev/null
    return $?
}

Verwenden Sie es wie folgt:

if var_defined foo; then
    echo "foo is defined"
else
    echo "foo is not defined"
fi

Rufgabe- ohne Argumente .. es gibt alle Vars definiert ..
die letzten, die auf der Liste würden die, die in Ihrem Skript definiert sein ..
so konnte man Rohr seine Ausgabe an etwas, das herausfinden könnte, was die Dinge sind definiert und was nicht

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top