Wie kann man am besten feststellen, ob eine Variable in bash leer ist ("")?
Ich habe gehört, es wird empfohlen, dies zu tun if [ "x$variable" = "x" ]
Ist das der richtige Weg? (Es muss etwas einfacher sein)
Wie kann man am besten feststellen, ob eine Variable in bash leer ist ("")?
Ich habe gehört, es wird empfohlen, dies zu tun if [ "x$variable" = "x" ]
Ist das der richtige Weg? (Es muss etwas einfacher sein)
Antworten:
Dies gibt true zurück, wenn eine Variable nicht gesetzt oder auf die leere Zeichenfolge ("") gesetzt ist.
if [ -z "$VAR" ];
if [ ! -z "$VAR" ];
-z
ist-n
if [ -n "$VAR" ];
$var
Element in einer Befehlszeile wird durch sein Leerzeichen in eine Liste von Parametern aufgeteilt, wobei "$var"
es sich immer nur um einen Parameter handelt. Das Zitieren von Variablen ist häufig eine gute Praxis und verhindert, dass Sie auf Dateinamen stoßen, die (unter anderem) Leerzeichen enthalten. Beispiel: a="x --help"
Versuchen cat $a
Sie es anschließend mit der Hilfeseite für cat
. Dann versuchen cat "$a"
Sie es - es wird (normalerweise) sagen cat: x --help: No such file or directory
. Kurz gesagt, zitiere früh und zitiere oft und du wirst es so gut wie nie bereuen.
Wenn Sie sich in Bash nicht mit der Portierbarkeit auf Shells befassen, die diese nicht unterstützen, sollten Sie immer die doppelte Klammer verwenden:
Eines der folgenden:
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
In Bash sind die Anführungszeichen in doppelten eckigen Klammern nicht erforderlich. Sie können den Test für eine Variable vereinfachen , die tut einen Wert enthalten:
if [[ $variable ]]
Diese Syntax ist mit ksh kompatibel (zumindest ksh93). Es funktioniert nicht in reinen POSIX- oder älteren Bourne-Shells wie sh oder dash.
Weitere Informationen zu den Unterschieden zwischen doppelten und einfachen eckigen Klammern finden Sie in meiner Antwort hier und in BashFAQ / 031 .
Sie können testen, ob eine Variable speziell nicht gesetzt ist (im Gegensatz zu einer leeren Zeichenfolge):
if [[ -z ${variable+x} ]]
wobei das "x" beliebig ist.
Wenn Sie wissen möchten, ob eine Variable null ist, aber nicht nicht gesetzt wurde:
if [[ -z $variable && ${variable+x} ]]
if [[ $variable ]]
hat für mich gut funktioniert und brauchte nicht einmal das set -u
, was für eine der anderen vorgeschlagenen Lösungen erforderlich war.
sh
anstelle von Bash. Wenn Sie die erweiterten Funktionen benötigen, verwenden Sie Bash und nutzen Sie es vollständig.
;
am Ende. Die then
kann in der nächsten Zeile ohne Semikolon stehen.
Eine Variable in bash (und jede POSIX-kompatible Shell) kann sich in einem von drei Zuständen befinden:
Die meiste Zeit müssen Sie nur wissen, ob eine Variable auf eine nicht leere Zeichenfolge festgelegt ist, aber gelegentlich ist es wichtig, zwischen nicht festgelegt und auf die leere Zeichenfolge festgelegt zu unterscheiden.
Die folgenden Beispiele zeigen, wie Sie die verschiedenen Möglichkeiten testen können und ob dies in bash oder einer POSIX-kompatiblen Shell funktioniert:
if [ -z "${VAR}" ]; then
echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
echo "VAR is either unset or set to a non-empty string"
fi
Hier ist das Gleiche, aber in handlicher Tabellenform:
+-------+-------+-----------+
VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ] | true | true | false |
| [ -z "${VAR+set}" ] | true | false | false |
| [ -z "${VAR-unset}" ] | false | true | false |
| [ -n "${VAR}" ] | false | false | true |
| [ -n "${VAR+set}" ] | false | true | true |
| [ -n "${VAR-unset}" ] | true | false | true |
+-----------------------+-------+-------+-----------+
Das ${VAR+foo}
Konstrukt wird zu der leeren Zeichenfolge erweitert, wenn VAR
es nicht festgelegt ist, oder zu, foo
wenn VAR
es auf etwas festgelegt ist (einschließlich der leeren Zeichenfolge).
Das ${VAR-foo}
Konstrukt wird auf den Wert von VAR
if set (einschließlich set für die leere Zeichenfolge) und foo
if unset erweitert. Dies ist nützlich, um vom Benutzer überschreibbare Standardeinstellungen bereitzustellen (z. B. ${COLOR-red}
zu verwenden, es red
sei denn, die Variable COLOR
wurde auf etwas festgelegt).
Der Grund, warum [ x"${VAR}" = x ]
oft empfohlen wird, um zu testen, ob eine Variable entweder nicht gesetzt oder auf die leere Zeichenfolge gesetzt ist, liegt darin, dass einige Implementierungen des [
Befehls (auch bekannt als test
) fehlerhaft sind. Wenn VAR
auf so etwas wie gesetzt ist -n
, werden einige Implementierungen bei der Angabe das Falsche tun, [ "${VAR}" = "" ]
da das erste Argument zu [
fälschlicherweise als -n
Operator interpretiert wird , nicht als Zeichenfolge.
[ -z "${VAR-set}" ]
.
set -u
oder set -o nounset
in bash anruft, führt der Test nur zum Fehler "bash: VAR: ungebundene Variable". Unter stackoverflow.com/a/13864829 finden Sie eine zuverlässigere Überprüfung auf nicht gesetzte Werte . Ich überprüfe, ob eine Variable null ist oder nicht [ -z "${VAR:-}" ]
. Meine Prüfung, ob eine Variable nicht leer ist, ist [ "${VAR:-}" ]
.
-z
ist der beste Weg.
Eine andere Option, die ich verwendet habe, ist das Setzen einer Variablen, die jedoch von einer anderen Variablen außer Kraft gesetzt werden kann, z
export PORT=${MY_PORT:-5432}
Wenn die $MY_PORT
Variable leer ist, PORT
wird sie auf 5432 gesetzt, andernfalls wird PORT auf den Wert von gesetzt MY_PORT
. Beachten Sie, dass die Syntax den Doppelpunkt und den Bindestrich enthält.
set -o nounset
in einigen Skripten tolerieren .
Eine Alternative, die ich gesehen habe, [ -z "$foo" ]
ist die folgende, aber ich bin nicht sicher, warum die Leute diese Methode anwenden, weiß jemand?
[ "x${foo}" = "x" ]
Wenn Sie nicht gesetzte Variablen (entweder von set -u
oder set -o nounset
) nicht zulassen, treten bei beiden Methoden Probleme auf. Hierfür gibt es eine einfache Lösung:
[ -z "${foo:-}" ]
Hinweis: Dadurch bleibt Ihre Variable undef.
-z
unter pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . Grundsätzlich ist es keine Alternative zu -z
. Vielmehr werden Fälle behandelt, in denen $foo
eine Erweiterung auf einen Meta-Buchstaben möglich ist, der verwirrt ist [
oder von test
diesem verwirrt wird. Wenn Sie am Anfang ein beliebiges Nicht-Metazeichen setzen, wird diese Möglichkeit ausgeschlossen.
Die Frage lautet , wie zu überprüfen ist, ob eine Variable eine leere Zeichenfolge ist, und die besten Antworten dafür sind bereits gegeben.
Aber ich bin hier gelandet, nachdem eine Zeit lang die Programmierung in PHP abgelaufen war, und was ich tatsächlich suchte, war eine Überprüfung wie die leere Funktion in PHP, die in einer Bash-Shell arbeitet.
Nachdem ich die Antworten gelesen hatte, stellte ich fest, dass ich in Bash nicht richtig dachte, aber in diesem Moment wäre eine Funktion wie leer in PHP in meinem Bash-Code soooo praktisch gewesen.
Wie ich glaube , dies anderen passieren kann, habe ich beschlossen , die PHP - leer - Funktion in bash zu konvertieren
Nach dem PHP - Handbuch :
Eine Variable wird als leer betrachtet, wenn sie nicht existiert oder wenn ihr Wert einer der folgenden Werte ist:
Natürlich können die Groß- und Kleinschreibung nicht in Bash konvertiert werden, daher werden sie weggelassen.
function empty
{
local var="$1"
# Return true if:
# 1. var is a null string ("" as empty string)
# 2. a non set variable is passed
# 3. a declared variable or array but without a value is passed
# 4. an empty array is passed
if test -z "$var"
then
[[ $( echo "1" ) ]]
return
# Return true if var is zero (0 as an integer or "0" as a string)
elif [ "$var" == 0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
# Return true if var is 0.0 (0 as a float)
elif [ "$var" == 0.0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
fi
[[ $( echo "" ) ]]
}
Anwendungsbeispiel:
if empty "${var}"
then
echo "empty"
else
echo "not empty"
fi
Demo:
das folgende Snippet:
#!/bin/bash
vars=(
""
0
0.0
"0"
1
"string"
" "
)
for (( i=0; i<${#vars[@]}; i++ ))
do
var="${vars[$i]}"
if empty "${var}"
then
what="empty"
else
what="not empty"
fi
echo "VAR \"$var\" is $what"
done
exit
Ausgänge:
VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty
In einer Bash-Logik können die Prüfungen auf Null in dieser Funktion imho Nebenprobleme verursachen. Jeder, der diese Funktion verwendet, sollte dieses Risiko bewerten und möglicherweise beschließen, diese Prüfungen abzuschneiden und nur die erste zu belassen.
empty
- warum hast du geschrieben [[ $( echo "1" ) ]] ; return
anstatt einfach return 1
?
Das gesamte Wenn-Dann und -Z sind nicht erforderlich.
["$ foo"] && echo "foo ist nicht leer" ["$ foo"] || echo "foo ist ja leer"
Dies gilt genau dann, wenn $ FOO gesetzt und leer ist:
[ "${FOO+x}" = x ] && [ -z "$FOO" ]
Persönlich bevorzugen klarere Weise zu überprüfen:
if [ "${VARIABLE}" == "" ]; then
echo VARIABLE is empty
else
echo VARIABLE is not empty
fi
Oneliner-Erweiterung der Lösung von duffbeer703 :
#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
Meine 5 Cent: Es gibt auch eine kürzere Syntax als if ...
diese:
VALUE="${1?"Usage: $0 value"}"
Diese Zeile setzt VALUE, wenn ein Argument angegeben wurde, und gibt im Fehlerfall eine Fehlermeldung mit der Nummer der Skriptzeile aus (und beendet die Skriptausführung).
Ein weiteres Beispiel finden Sie im Abs -Guide (Suche nach «Beispiel 10-7»).
Keine exakte Antwort, aber auf diesen Trick gestoßen. Wenn die Zeichenfolge, nach der Sie suchen, von "einem Befehl" stammt, können Sie den Befehl tatsächlich in einer Umgebung speichern. Variable und führen Sie es dann jedes Mal für die if-Anweisung aus, dann sind keine Klammern erforderlich!
Zum Beispiel dieser Befehl, der bestimmt, ob Sie unter Debian sind:
grep debian /proc/version
vollständiges Beispiel:
IS_DEBIAN="grep -i debian /proc/version"
if $IS_DEBIAN; then
echo 'yes debian'
else
echo 'non debian'
fi
Dies ist also wie eine indirekte Methode (es wird jedes Mal neu ausgeführt), um nach einer leeren Zeichenfolge zu suchen (es wird zufällig nach einer Fehlerantwort vom Befehl gesucht, es wird jedoch auch eine leere Zeichenfolge zurückgegeben).