it-swarm.com.de

Wie überprüfe ich, ob eine Variable in Bash gesetzt ist?

Woher weiß ich, ob eine Variable in Bash gesetzt ist?

Wie überprüfe ich beispielsweise, ob der Benutzer einer Funktion den ersten Parameter gegeben hat?

function a {
    # if $1 is set ?
}
1341
prosseek

(Normalerweise) Der richtige Weg

if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi

wobei ${var+x} ein Parametererweiterung ist, das nichts ergibt, wenn var nicht gesetzt ist, und ansonsten die Zeichenfolge x ersetzt.

Zitate Exkurs

Anführungszeichen können weggelassen werden (wir können also ${var+x} anstelle von "${var+x}" sagen), da diese Syntax und Verwendung garantiert, dass dies nur zu etwas erweitert wird, das keine Anführungszeichen erfordert (da es entweder zu x erweitert wird). (enthält keine Wortumbrüche, sodass keine Anführungszeichen erforderlich sind) oder nichts (was zu [ -z ] führt, was günstigerweise den gleichen Wert ergibt (true) wie [ -z "" ]).

Obwohl Anführungszeichen sicher weggelassen werden können und es nicht für alle sofort offensichtlich war (es war nicht einmal für den ersten Autor dieser Erklärung zu Anführungszeichen , der auch ein wichtiger Bash-Codierer ist), würde dies der Fall sein Manchmal ist es besser, die Lösung mit Anführungszeichen wie [ -z "${var+x}" ] zu schreiben, und zwar zum sehr geringen Preis einer O(1) Geschwindigkeitsstrafe. Der erste Autor fügte dies auch als Kommentar neben dem Code hinzu und verwendete dabei die URL zu dieser Antwort. Diese enthält nun auch die Erklärung, warum die Anführungszeichen sicher weggelassen werden können.

(Oft) Der falsche Weg

if [ -z "$var" ]; then echo "var is blank"; else echo "var is set to '$var'"; fi

Dies ist häufig falsch, da nicht zwischen einer nicht festgelegten Variablen und einer Variablen unterschieden wird, die auf die leere Zeichenfolge festgelegt ist. Das heißt, wenn var='', dann gibt die obige Lösung "var is blank" aus.

Die Unterscheidung zwischen "nicht gesetzt" und "auf die leere Zeichenfolge gesetzt" ist in Situationen wichtig, in denen der Benutzer eine Erweiterung oder eine zusätzliche Liste von Eigenschaften angeben muss und diese nicht angegeben werden, wobei die Angabe der leeren Zeichenfolge standardmäßig einem nicht leeren Wert entspricht Lassen Sie das Skript eine leere Erweiterung oder eine Liste zusätzlicher Eigenschaften verwenden.

Die Unterscheidung ist jedoch möglicherweise nicht in jedem Szenario wesentlich. In diesen Fällen ist [ -z "$var" ] in Ordnung.

2016
Lionel

Verwenden Sie diese Option, um nach Zeichenfolgenvariablen zu suchen, die nicht null oder nicht null sind

if [ -n "$1" ]

Es ist das Gegenteil von -z. Ich benutze -n mehr als -z.

Sie würden es wie folgt verwenden:

if [ -n "$1" ]; then
  echo "You supplied the first parameter!"
else
  echo "First parameter not supplied."
fi
793
mbrannig

Hier erfahren Sie, wie Sie testen, ob ein Parameter nicht gesetzt oder leer ("Null") oder gesetzt ist mit einem Wert :

+--------------------+----------------------+-----------------+-----------------+
|                    |       parameter      |     parameter   |    parameter    |
|                    |   Set and Not Null   |   Set But Null  |      Unset      |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-Word} | substitute parameter | substitute Word | substitute Word |
| ${parameter-Word}  | substitute parameter | substitute null | substitute Word |
| ${parameter:=Word} | substitute parameter | assign Word     | assign Word     |
| ${parameter=Word}  | substitute parameter | substitute null | assign Word     |
| ${parameter:?word} | substitute parameter | error, exit     | error, exit     |
| ${parameter?word}  | substitute parameter | substitute null | error, exit     |
| ${parameter:+Word} | substitute Word      | substitute null | substitute null |
| ${parameter+Word}  | substitute Word      | substitute Word | substitute null |
+--------------------+----------------------+-----------------+-----------------+

Quelle: POSIX: Parametererweiterung :

In allen Fällen, die mit "Ersatz" angezeigt werden, wird der Ausdruck durch den angezeigten Wert ersetzt. In allen Fällen, die mit "assign" angezeigt werden, wird dem Parameter dieser Wert zugewiesen, der auch den Ausdruck ersetzt.

433
Jens

Während die meisten der hier angegebenen Techniken korrekt sind, unterstützt bash 4.2 einen tatsächlichen Test auf das Vorhandensein einer Variablen ( man bash ), anstatt den Wert der Variablen zu testen.

[[ -v foo ]]; echo $?
# 1

foo=bar
[[ -v foo ]]; echo $?
# 0

foo=""
[[ -v foo ]]; echo $?
# 0

Insbesondere wird dieser Ansatz keinen Fehler verursachen, wenn er verwendet wird, um im set -u/set -o nounset -Modus nach einer nicht gesetzten Variablen zu suchen, im Gegensatz zu vielen anderen Ansätzen, wie z. B. der Verwendung von [ -z.

203
Russell Harmon

Es gibt viele Möglichkeiten, dies zu tun:

if [ -z "$1" ]

Dies ist erfolgreich, wenn $ 1 null oder nicht festgelegt ist

174
ennuikiller

Um zu sehen, ob eine Variable nicht leer ist, benutze ich

if [[ $var ]]; then ...       # `$var' expands to a nonempty string

Das Gegenteil testet, ob eine Variable entweder nicht gesetzt oder leer ist:

if [[ ! $var ]]; then ...     # `$var' expands to the empty string (set or not)

Um zu sehen, ob eine Variable gesetzt ist (leer oder nicht leer), benutze ich

if [[ ${var+x} ]]; then ...   # `var' exists (empty or nonempty)
if [[ ${1+x} ]]; then ...     # Parameter 1 exists (empty or nonempty)

Das Gegenteil testet, ob eine Variable nicht gesetzt ist:

if [[ ! ${var+x} ]]; then ... # `var' is not set at all
if [[ ! ${1+x} ]]; then ...   # We were called with no arguments
62
phkoester

Ich finde die POSIX-Tabelle immer in andere Antwort slow to grok, also hier meine Ansicht dazu:

   +----------------------+------------+-----------------------+-----------------------+
   |   if VARIABLE is:    |    set     |         empty         |        unset          |
   +----------------------+------------+-----------------------+-----------------------+
 - |  ${VARIABLE-default} | $VARIABLE  |          ""           |       "default"       |
 = |  ${VARIABLE=default} | $VARIABLE  |          ""           | $(VARIABLE="default") |
 ? |  ${VARIABLE?default} | $VARIABLE  |          ""           |       exit 127        |
 + |  ${VARIABLE+default} | "default"  |       "default"       |          ""           |
   +----------------------+------------+-----------------------+-----------------------+
:- | ${VARIABLE:-default} | $VARIABLE  |       "default"       |       "default"       |
:= | ${VARIABLE:=default} | $VARIABLE  | $(VARIABLE="default") | $(VARIABLE="default") |
:? | ${VARIABLE:?default} | $VARIABLE  |       exit 127        |       exit 127        |
:+ | ${VARIABLE:+default} | "default"  |          ""           |          ""           |
   +----------------------+------------+-----------------------+-----------------------+

Beachten Sie, dass jede Gruppe (mit und ohne vorangestelltem Doppelpunkt) die gleichen set ​​und nset ​​Fälle hat. Das einzige, was sich unterscheidet, ist, wie leer Fälle werden behandelt.

Mit dem vorangestellten Doppelpunkt sind die Fälle leer und nicht gesetzt ​​identisch, daher würde ich diese nach Möglichkeit verwenden (dh := verwenden, nicht nur = , weil der leere Fall inkonsistent ist).

Überschriften:

  • set ​​bedeutet VARIABLE ist nicht leer (VARIABLE="something")
  • leer bedeutet VARIABLE ist leer/null (VARIABLE="")
  • nset ​​bedeutet, dass VARIABLE nicht existiert (unset VARIABLE)

Werte:

  • $VARIABLE bedeutet, dass das Ergebnis der ursprüngliche Wert der Variablen ist.
  • "default" bedeutet, dass das Ergebnis die angegebene Ersatzzeichenfolge war.
  • "" bedeutet, dass das Ergebnis null ist (eine leere Zeichenfolge).
  • exit 127 bedeutet, dass das Skript mit dem Beendigungscode 127 nicht mehr ausgeführt wird.
  • $(VARIABLE="default") bedeutet, dass das Ergebnis der ursprüngliche Wert der Variablen ist nd Die bereitgestellte Ersatzzeichenfolge wird der Variablen für die zukünftige Verwendung zugewiesen.
60
deizel

Bei einer modernen Version von Bash (4.2 oder neuer, ich weiß es nicht genau) würde ich Folgendes versuchen:

if [ ! -v SOMEVARIABLE ] #note the lack of a $ sigil
then
    echo "Variable is unset"
Elif [ -z "$SOMEVARIABLE" ]
then
    echo "Variable is set to an empty string"
else
    echo "Variable is set to some string"
fi
31
Seamus Connor
if [ "$1" != "" ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

Obwohl es normalerweise am besten ist, für Argumente $ # zu testen, was meiner Meinung nach die Anzahl der Argumente ist.

if [ $# -gt 0 ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi
20
Paul Creasey

Sie möchten beenden, wenn es nicht eingestellt ist

Das hat bei mir funktioniert. Ich wollte, dass mein Skript mit einer Fehlermeldung beendet wird, wenn kein Parameter festgelegt wurde.

#!/usr/bin/env bash

set -o errexit

# Get the value and empty validation check all in one
VER="${1:?You must pass a version of the format 0.0.0 as the only argument}"

Dies gibt beim Ausführen einen Fehler zurück

[email protected]:~$ ./setver.sh
./setver.sh: line 13: 1: You must pass a version of the format 0.0.0 as the only argument

Nur prüfen, kein Beenden - Leer und Nicht gesetzt sind UNGÜLTIG

Probieren Sie diese Option aus, wenn Sie nur prüfen möchten, ob der Wert auf GÜLTIG oder nicht gesetzt/leer = UNGÜLTIG gesetzt ist.

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
if [ "${TUNSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

Oder auch kurze Tests ;-)

[ "${TSET:-}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY:-}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET:-}" ] && echo "VALID" || echo "INVALID"

Nur prüfen, kein Beenden - Nur leer ist UNGÜLTIG

Und das ist die Antwort auf die Frage. Verwenden Sie diese Option, wenn Sie nur prüfen möchten, ob der Wert set/empty = VALID oder unset = INVALID ist.

HINWEIS: Die "1" in "..- 1}" ist unbedeutend. Es kann sich um alles handeln (wie x).

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TUNSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

Kurze Tests

[ "${TSET+1}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY+1}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET+1}" ] && echo "VALID" || echo "INVALID"

Ich widme diese Antwort @ mklement0 (Kommentaren), die mich herausforderten, die Frage genau zu beantworten.

Referenz http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

16
Jarrod Chesney

Verwenden Sie [ -n "$x" ], um zu überprüfen, ob für eine Variable ein nicht leerer Wert festgelegt wurde, wie bereits von anderen angegeben.

In den meisten Fällen empfiehlt es sich, eine Variable mit einem leeren Wert wie eine nicht gesetzte Variable zu behandeln. Sie können die beiden jedoch unterscheiden, wenn Sie Folgendes benötigen: [ -n "${x+set}" ] ("${x+set}" wird zu set erweitert, wenn x festgelegt ist, und zu der leeren Zeichenfolge, wenn x nicht festgelegt ist ).

Um zu überprüfen, ob ein Parameter übergeben wurde, testen Sie $#. Dies ist die Anzahl der Parameter, die an die Funktion (oder an das Skript, wenn keine Funktion vorhanden ist) übergeben wurden (siehe Pauls Antwort ). .

14
Gilles

Lesen Sie den Abschnitt "Parametererweiterung" auf der Manpage bash. Die Parametererweiterung bietet keinen allgemeinen Test für eine Variable, die festgelegt wird. Sie können jedoch verschiedene Aktionen für einen Parameter ausführen, wenn dieser nicht festgelegt ist.

Zum Beispiel:

function a {
    first_arg=${1-foo}
    # rest of the function
}

setzt first_arg gleich $1, wenn es zugewiesen ist, andernfalls wird der Wert "foo" verwendet. Wenn a unbedingt einen einzelnen Parameter annehmen muss und kein guter Standardwert vorhanden ist, können Sie den Vorgang mit einer Fehlermeldung beenden, wenn kein Parameter angegeben wird:

function a {
    : ${1?a must take a single argument}
    # rest of the function
}

(Beachten Sie die Verwendung von : als Null-Befehl, der nur die Werte seiner Argumente erweitert. In diesem Beispiel möchten wir nichts mit $1 tun, sondern einfach beenden, wenn es nicht gesetzt ist )

14
chepner

In bash können Sie -v innerhalb des [[ ]]-Builtins verwenden:

#! /bin/bash -u

if [[ ! -v SOMEVAR ]]; then
    SOMEVAR='hello'
fi

echo $SOMEVAR
13
AlejandroVD

Für diejenigen, die in einem Skript mit set -u nach nicht gesetztem oder leerem suchen:

_if [ -z "${var-}" ]; then
   echo "Must provide var environment variable. Exiting...."
   exit 1
fi
_

Die reguläre _[ -z "$var" ]_ Prüfung schlägt mit _var; unbound variable_ fehl, wenn _set -u_ aber _[ -z "${var-}" ]_ erweitert zu leerer Zeichenfolge, wenn var ohne Fehler nicht gesetzt ist.

12
ecerulm

Hinweis

Aufgrund des bash -Tags gebe ich eine stark auf Bash ausgerichtete Antwort.

Kurze Antwort

Solange Sie nur mit benannten Variablen in Bash arbeiten, sollte diese Funktion Ihnen immer mitteilen, ob die Variable gesetzt wurde, auch wenn es sich um ein leeres Array handelt.

is-variable-set() {
    declare -p $1 &>dev/null
}

Warum funktioniert das?

Wenn in Bash (mindestens 3.0) var eine deklarierte/gesetzte Variable ist, gibt declare -p var Einen Befehl declare aus, mit dem die Variable var gesetzt wird ] _ auf den aktuellen Typ und Wert und gibt den Statuscode 0 (Erfolg) zurück. Wenn var nicht deklariert ist, gibt declare -p var Eine Fehlermeldung an stderr aus und gibt den Statuscode 1 Zurück. Mit &>/dev/null Werden die regulären stdout und stderr Ausgaben auf /dev/null Umgeleitet, ohne dass der Statuscode geändert wird. Daher gibt die Funktion nur den Statuscode zurück.

Warum andere Methoden in Bash (manchmal) fehlschlagen

  • [ -n "$var" ]: Prüft nur, ob ${var[0]} Nicht leer ist. (In Bash ist $var Dasselbe wie ${var[0]}.)
  • [ -n "${var+x}" ]: Prüft nur, ob ${var[0]} Eingestellt ist.
  • [ "${#var[@]}" != 0 ]: Prüft nur, ob mindestens ein Index von $var Gesetzt ist.

Wenn diese Methode in Bash fehlschlägt

Dies funktioniert nur für benannte Variablen (einschließlich $_), Nicht für bestimmte spezielle Variablen ($!, [email protected], $#, $$, $*, $?, $-, $0, $1, $2, ... und alles, was ich habe Vergessene). Da es sich bei keinem dieser Arrays um Arrays handelt, funktioniert der POSIX-Stil [ -n "${var+x}" ] Für alle diese speziellen Variablen. Aber hüte dich davor, es in eine Funktion zu packen, da viele spezielle Variablen Werte/Existenz ändern, wenn Funktionen aufgerufen werden.

Shell-Kompatibilitätshinweis

Wenn Ihr Skript Arrays enthält und Sie versuchen, es mit so vielen Shells wie möglich kompatibel zu machen, sollten Sie typeset -p Anstelle von declare -p Verwenden. Ich habe gelesen, dass ksh nur das erstere unterstützt, dies aber nicht testen konnte. Ich weiß, dass Bash 3.0+ und Zsh 5.5.1 beide typeset -p Und declare -p Unterstützen und sich nur darin unterscheiden, welches eine Alternative für das andere ist. Aber ich habe keine Unterschiede über diese beiden Schlüsselwörter hinaus getestet, und ich habe keine anderen Shells getestet.

Wenn Sie ein POSIX-kompatibles Skript benötigen, können Sie keine Arrays verwenden. Ohne Arrays funktioniert [ -n "{$var+x}" ].

Vergleichscode für verschiedene Methoden in Bash

Diese Funktion deaktiviert die Variable var, evals des übergebenen Codes, führt Tests durch, um festzustellen, ob var durch den Code evald festgelegt wurde, und zeigt schließlich den resultierenden Status an Codes für die verschiedenen Tests.

Ich überspringe test -v var, [ -v var ] Und [[ -v var ]], Weil sie identische Ergebnisse wie der POSIX-Standard [ -n "${var+x}" ] Liefern, während Bash 4.2+ erforderlich ist. Ich überspringe auch typeset -p, Weil es dasselbe ist wie declare -p In den Shells, die ich getestet habe (Bash 3.0 bis 5.0 und Zsh 5.5.1).

is-var-set-after() {
    # Set var by passed expression.
    unset var
    eval "$1"

    # Run the tests, in increasing order of accuracy.
    [ -n "$var" ] # (index 0 of) var is nonempty
    nonempty=$?
    [ -n "${var+x}" ] # (index 0 of) var is set, maybe empty
    plus=$?
    [ "${#var[@]}" != 0 ] # var has at least one index set, maybe empty
    count=$?
    declare -p var &>/dev/null # var has been declared (any type)
    declared=$?

    # Show test results.
    printf '%30s: %2s %2s %2s %2s\n' "$1" $nonempty $plus $count $declared
}

Testfallcode

Beachten Sie, dass die Testergebnisse möglicherweise unerwartet sind, da Bash nicht numerische Array-Indizes als "0" behandelt, wenn die Variable nicht als assoziatives Array deklariert wurde. Assoziative Arrays sind nur in Bash 4.0+ gültig.

# Header.
printf '%30s: %2s %2s %2s %2s\n' "test" '-n' '+x' '#@' '-p'
# First 5 tests: Equivalent to setting 'var=foo' because index 0 of an
# indexed array is also the nonindexed value, and non-numerical
# indices in an array not declared as associative are the same as
# index 0.
is-var-set-after "var=foo"                        #  0  0  0  0
is-var-set-after "var=(foo)"                      #  0  0  0  0
is-var-set-after "var=([0]=foo)"                  #  0  0  0  0
is-var-set-after "var=([x]=foo)"                  #  0  0  0  0
is-var-set-after "var=([y]=bar [x]=foo)"          #  0  0  0  0
# '[ -n "$var" ]' fails when var is empty.
is-var-set-after "var=''"                         #  1  0  0  0
is-var-set-after "var=([0]='')"                   #  1  0  0  0
# Indices other than 0 are not detected by '[ -n "$var" ]' or by
# '[ -n "${var+x}" ]'.
is-var-set-after "var=([1]='')"                   #  1  1  0  0
is-var-set-after "var=([1]=foo)"                  #  1  1  0  0
is-var-set-after "declare -A var; var=([x]=foo)"  #  1  1  0  0
# Empty arrays are only detected by 'declare -p'.
is-var-set-after "var=()"                         #  1  1  1  0
is-var-set-after "declare -a var"                 #  1  1  1  0
is-var-set-after "declare -A var"                 #  1  1  1  0
# If 'var' is unset, then it even fails the 'declare -p var' test.
is-var-set-after "unset var"                      #  1  1  1  1

Ausgang testen

Die Testmnemoniken in der Kopfzeile entsprechen [ -n "$var" ], [ -n "${var+x}" ], [ "${#var[@]}" != 0 ] Bzw. declare -p var.

                         test: -n +x #@ -p
                      var=foo:  0  0  0  0
                    var=(foo):  0  0  0  0
                var=([0]=foo):  0  0  0  0
                var=([x]=foo):  0  0  0  0
        var=([y]=bar [x]=foo):  0  0  0  0
                       var='':  1  0  0  0
                 var=([0]=''):  1  0  0  0
                 var=([1]=''):  1  1  0  0
                var=([1]=foo):  1  1  0  0
declare -A var; var=([x]=foo):  1  1  0  0
                       var=():  1  1  1  0
               declare -a var:  1  1  1  0
               declare -A var:  1  1  1  0
                    unset var:  1  1  1  1

Zusammenfassung

  • declare -p var &>/dev/null ist (100%?) Zuverlässig für das Testen benannter Variablen in Bash seit mindestens 3.0.
  • [ -n "${var+x}" ] ist in POSIX-konformen Situationen zuverlässig, kann jedoch keine Arrays verarbeiten.
  • Es gibt weitere Tests, um zu überprüfen, ob eine Variable nicht leer ist, und um zu überprüfen, ob in anderen Shells Variablen deklariert wurden. Diese Tests eignen sich jedoch weder für Bash- noch für POSIX-Skripte.
11
Mark Haferkamp

Die Verwendung von [[ -z "$var" ]] ist der einfachste Weg, um festzustellen, ob eine Variable festgelegt wurde oder nicht, aber diese Option -z unterscheidet nicht zwischen einer nicht festgelegten Variablen und einer Variablen, die auf eine leere Zeichenfolge festgelegt ist:

$ set=''
$ [[ -z "$set" ]] && echo "Set" || echo "Unset" 
Unset
$ [[ -z "$unset" ]] && echo "Set" || echo "Unset"
Unset

Es ist am besten, es nach dem Variablentyp zu überprüfen: Umgebungsvariable, Parameter oder reguläre Variable.

Für eine Umgebungsvariable:

[[ $(env | grep "varname=" | wc -l) -eq 1 ]] && echo "Set" || echo "Unset"

Für einen Parameter (um beispielsweise die Existenz des Parameters $5 zu überprüfen):

[[ $# -ge 5 ]] && echo "Set" || echo "Unset"

Für eine reguläre Variable (mit einer Hilfsfunktion auf elegante Weise):

function declare_var {
   declare -p "$1" &> /dev/null
}
declare_var "var_name" && echo "Set" || echo "Unset"

Anmerkungen:

  • $#: gibt die Anzahl der Positionsparameter an.
  • declare -p: gibt die Definition der als Parameter übergebenen Variablen an. Wenn es existiert, wird 0 zurückgegeben, wenn nicht, wird 1 zurückgegeben und eine Fehlermeldung ausgegeben.
  • &> /dev/null: unterdrückt die Ausgabe von declare -p, ohne den Rückkehrcode zu beeinflussen.
5
Peregring-lk

Die obigen Antworten funktionieren nicht, wenn die Bash-Option set -u aktiviert ist. Auch sind sie nicht dynamisch, z. B. wie zu testen ist eine Variable mit dem Namen "Dummy" definiert? Versuche dies:

is_var_defined()
{
    if [ $# -ne 1 ]
    then
        echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
        exit 1
    fi
    # Tricky.  Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
    # is defined with this construct: [ ! -z "$var" ].  Instead, we must use default value
    # substitution with this construct: [ ! -z "${var:-}" ].  Normally, a default value follows the
    # operator ':-', but here we leave it blank for empty (null) string.  Finally, we need to
    # substitute the text from $1 as 'var'.  This is not allowed directly in Bash with this
    # construct: [ ! -z "${$1:-}" ].  We need to use indirection with eval operator.
    # Example: $1="var"
    # Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
    # Code  execute: [ ! -z ${var:-} ]
    eval "[ ! -z \${$1:-} ]"
    return $?  # Pedantic.
}

Siehe auch: Wie teste ich in Bash, ob eine Variable im "-u" -Modus definiert ist?

4
kevinarpe

Du kannst tun:

function a {
        if [ ! -z "$1" ]; then
                echo '$1 is set'
        fi
}
4
codaddict

Mein bevorzugter Weg ist dieser:

$var=10
$if ! ${var+false};then echo "is set";else echo "NOT set";fi
is set
$unset var
$if ! ${var+false};then echo "is set";else echo "NOT set";fi
NOT set

Wenn also eine Variable gesetzt ist, wird sie "eine Negation des resultierenden false" (was true = "gesetzt ist").

Und wenn es nicht gesetzt ist, wird es "eine Negation des resultierenden true" (als das leere Ergebnis wird true ausgewertet) (so endet es als false = "NICHT gesetzt ").

2
Aquarius Power

In einer Shell können Sie den Operator -z verwenden, der True ist, wenn die Länge der Zeichenfolge Null ist.

Ein einfacher Einzeiler zum Festlegen des Standardwerts MY_VAR, wenn dieser nicht festgelegt ist. Andernfalls können Sie optional die folgende Meldung anzeigen:

[[ -z "$MY_VAR" ]] && MY_VAR="default"
[[ -z "$MY_VAR" ]] && MY_VAR="default" || echo "Variable already set."
1
kenorb

Das benutze ich jeden Tag:

#
# Check if a variable is set
#   param1  name of the variable
#
function is_set()
{
    [[ -n "${1}" ]] && test -n "$(eval "echo "\${${1}+x}"")"
}

Dies funktioniert gut unter Linux und Solaris bis hinunter zu Bash 3.0.

bash-3.00$ myvar="TEST"
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ mavar=""
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ unset myvar
bash-3.00$ is_set myvar ; echo $?
1
0
fr00tyl00p

Nachdem Sie alle Antworten überflogen haben, funktioniert dies auch:

if [[ -z $SOME_VAR ]]; then read -p "Enter a value for SOME_VAR: " SOME_VAR; fi
echo "SOME_VAR=$SOME_VAR"

wenn Sie nicht SOME_VAR anstelle dessen setzen, was ich $SOME_VAR habe, wird es auf einen leeren Wert gesetzt. $ ist erforderlich, damit dies funktioniert.

0
Hatem Jaber

Ich benutze dieses immer, da es für jeden, der den Code zum ersten Mal sieht, leicht zu verstehen ist:

if [ "$variable" = "" ]
    then
    echo "Variable X is empty"
fi

Und wenn Sie überprüfen möchten, ob nicht leer;

if [ ! "$variable" = "" ]
    then
    echo "Variable X is not empty"
fi

Das ist es.

0
mijnnaam

Ich habe einen (viel) besseren Code dafür gefunden, wenn Sie in [email protected] nach etwas suchen möchten.

 wenn [[$ 1 = ""]] 
 dann 
 echo '$ 1 ist leer' 
 sonst 
 echo '$ 1 ist voll' 
 fi 

Warum das alles? Alles in [email protected] existiert in Bash, aber standardmäßig ist es leer, sodass test -z und test -n Ihnen nicht weiterhelfen konnten.

pdate: Sie können auch die Anzahl der Zeichen in einem Parameter zählen.

 wenn [$ {# 1} = 0] 
 dann 
 echo '$ 1 ist leer' 
 sonst 
 echo '$ 1 ist voll' 
 fi 
0
Zlatan
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi
0
Graham

Ich mag Hilfsfunktionen, um die groben Details von bash zu verbergen. In diesem Fall erhöht dies die (verborgene) Grobheit:

# The first ! negates the result (can't use -n to achieve this)
# the second ! expands the content of varname (can't do ${$varname})
function IsDeclared_Tricky
{
  local varname="$1"
  ! [ -z ${!varname+x} ]
}

Da ich zum ersten Mal Fehler in dieser Implementierung hatte (inspiriert von den Antworten von Jens und Lionel), kam ich auf eine andere Lösung:

# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
  declare -p $1 &>/dev/null
}

Ich finde es klarer, schüchterner und leichter zu verstehen/zu merken. Testfall zeigt, dass es äquivalent ist:

function main()
{
  declare -i xyz
  local foo
  local bar=
  local baz=''

  IsDeclared_Tricky xyz; echo "IsDeclared_Tricky xyz: $?"
  IsDeclared_Tricky foo; echo "IsDeclared_Tricky foo: $?"
  IsDeclared_Tricky bar; echo "IsDeclared_Tricky bar: $?"
  IsDeclared_Tricky baz; echo "IsDeclared_Tricky baz: $?"

  IsDeclared xyz; echo "IsDeclared xyz: $?"
  IsDeclared foo; echo "IsDeclared foo: $?"
  IsDeclared bar; echo "IsDeclared bar: $?"
  IsDeclared baz; echo "IsDeclared baz: $?"
}

main

Der Testfall zeigt auch, dass local varNOT var deklariert (sofern nicht gefolgt von '='). Eine ganze Weile dachte ich, ich hätte Variablen auf diese Weise deklariert, nur um jetzt herauszufinden, dass ich nur meine Absicht ausgedrückt habe ... Es ist wohl ein No-Op.

IsDeclared_Tricky xyz: 1
IsDeclared_Tricky foo: 1
IsDeclared_Tricky Balken: 0
IsDeclared_Tricky baz: 0
IsDeclared xyz: 1
IsDeclared foo: 1
IsDeclared Balken: 0
IsDeclared baz: 0

BONUS: usecase

Ich benutze diesen Test hauptsächlich, um Funktionen auf etwas "elegante" und sichere Weise (fast wie eine Schnittstelle ...) zu parametrisieren (und zurückzugeben) :

#auxiliary functions
function die()
{
  echo "Error: $1"; exit 1
}

function assertVariableDeclared()
{
  IsDeclared "$1" || die "variable not declared: $1"
}

function expectVariables()
{
  while (( $# > 0 )); do
    assertVariableDeclared $1; shift
  done
}

# actual example
function exampleFunction()
{
  expectVariables inputStr outputStr
  outputStr="$inputStr world!"
}

function bonus()
{
  local inputStr='Hello'
  local outputStr= # remove this to trigger error
  exampleFunction
  echo $outputStr
}

bonus

Wenn mit all aufgerufen wird, müssen die Variablen deklariert werden:

Hallo Welt!

sonst:

Fehler: Variable nicht deklariert: outputStr

0
Daniel S
if [[ ${1:+isset} ]]
then echo "It was set and not null." >&2
else echo "It was not set or it was null." >&2
fi

if [[ ${1+isset} ]]
then echo "It was set but might be null." >&2
else echo "It was was not set." >&2
fi
0
solidsnack
[[ $foo ]]

Oder

(( ${#foo} ))

Oder

let ${#foo}

Oder

declare -p foo
0
Steven Penny