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 ?
}
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.
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.
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.
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
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.
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
.
Es gibt viele Möglichkeiten, dies zu tun:
if [ -z "$1" ]
Dies ist erfolgreich, wenn $ 1 null oder nicht festgelegt ist
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
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:
VARIABLE
ist nicht leer (VARIABLE="something"
)VARIABLE
ist leer/null (VARIABLE=""
)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.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
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
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
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"
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
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 ). .
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 )
In bash können Sie -v
innerhalb des [[ ]]
-Builtins verwenden:
#! /bin/bash -u
if [[ ! -v SOMEVAR ]]; then
SOMEVAR='hello'
fi
echo $SOMEVAR
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.
Aufgrund des bash
-Tags gebe ich eine stark auf Bash ausgerichtete 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
}
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.
[ -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.
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.
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}" ]
.
Diese Funktion deaktiviert die Variable var
, eval
s des übergebenen Codes, führt Tests durch, um festzustellen, ob var
durch den Code eval
d 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
}
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
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
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.
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 vondeclare -p
, ohne den Rückkehrcode zu beeinflussen.
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?
Du kannst tun:
function a {
if [ ! -z "$1" ]; then
echo '$1 is set'
fi
}
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 ").
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."
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
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.
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.
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
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi
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 var
NOT 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
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
[[ $foo ]]
Oder
(( ${#foo} ))
Oder
let ${#foo}
Oder
declare -p foo