variable Testen Sie die Länge der Zeichenfolge ungleich Null in Bash:[-n "$ var"] oder




bash test (5)

Verwenden Sie case/esac zum Testen

case "$var" in
  "") echo "zero length";;
esac

Ich habe gesehen, dass Bash-Skripte auf zwei verschiedene Arten auf Nicht-Null-Länge-Strings testen. Die meisten Skripte verwenden die Option -n:

#!/bin/bash
# With the -n option
if [ -n "$var" ]; then
  # Do something when var is non-zero length
fi

Aber die Option -n wird nicht wirklich benötigt:

# Without the -n option
if [ "$var" ]; then
  # Do something when var is non-zero length
fi

Welcher ist der bessere Weg?

Ähnlich ist der bessere Weg zum Testen auf Null:

if [ -z "$var" ]; then
  # Do something when var is zero-length
fi

oder

if [ ! "$var" ]; then
  # Do something when var is zero-length
fi

Eine alternative und vielleicht transparentere Möglichkeit, eine leere env-Variable zu bewerten, ist die Verwendung von ...

  if [ "x$ENV_VARIABLE" != "x" ] ; then
      echo 'ENV_VARIABLE contains something'
  fi

Diese Antwort seit diesem Beitrag zu veröffentlichen ist als nur bash markiert.

Es ist besser, die mächtigeren [[ so weit wie Bash betrifft] zu verwenden.

Übliche Fälle

if [[ $var ]]; then   # var is set and it is not empty
if [[ ! $var ]]; then # var is not set or it is set to an empty string

Die obigen zwei Konstrukte sehen sauber und lesbar aus. Sie sollten in den meisten Fällen ausreichen.

Beachten Sie, dass wir die Variablenerweiterungen innerhalb [[ da keine Gefahr der Worttrennung und globbing .

Seltene Fälle

In dem seltenen Fall, dass wir unterscheiden müssen zwischen "auf einen leeren String gesetzt" und "überhaupt nicht gesetzt" können wir diese verwenden:

if [[ ${var+x} ]]; then           # var is set but it could be empty
if [[ ! ${var+x} ]]; then         # var is not set
if [[ ${var+x} && ! $var ]]; then # var is set and is empty

Wir können auch den -v Test verwenden:

if [[ -v var ]]; then             # var is set but it could be empty
if [[ ! -v var ]]; then           # var is not set
if [[ -v var && ! $var ]]; then   # var is set and is empty

Mehr Diskussion

Es gibt eine Menge Fragen und Antworten dazu. Hier sind ein paar:

  • Wie überprüft man, ob eine Variable in Bash gesetzt ist?
  • Sind doppelte eckige Klammern [[]] gegenüber einzelnen eckigen Klammern [] in Bash vorzuziehen?
  • Was ist der Unterschied zwischen einfachen und doppelten eckigen Klammern in Bash?
  • Eine ausgezeichnete answer von mklement0 wo er über [[ vs [

Edit: Dies ist eine vollständigere Version, die mehr Unterschiede zwischen [ (aka test ) und [[ .

Die folgende Tabelle zeigt, ob eine Variable zitiert wird oder nicht, ob Sie einfache oder doppelte Klammern verwenden und ob die Variable nur ein Leerzeichen enthält, ob die Verwendung eines Tests mit oder ohne -n/-z zur Überprüfung geeignet ist Variable.

       1a    2a    3a    4a    5a    6a    |1b    2b    3b    4b    5b    6b
       [     ["    [-n   [-n"  [-z   [-z"  |[[    [["   [[-n  [[-n" [[-z  [[-z"
unset: false false true  false true  true  |false false false false true  true
null : false false true  false true  true  |false false false false true  true
space: false true  true  true  true  false |true  true  true  true  false false
zero : true  true  true  true  false false |true  true  true  true  false false
digit: true  true  true  true  false false |true  true  true  true  false false
char : true  true  true  true  false false |true  true  true  true  false false
hyphn: true  true  true  true  false false |true  true  true  true  false false
two  : -err- true  -err- true  -err- false |true  true  true  true  false false
part : -err- true  -err- true  -err- false |true  true  true  true  false false
Tstr : true  true  -err- true  -err- false |true  true  true  true  false false
Fsym : false true  -err- true  -err- false |true  true  true  true  false false
T=   : true  true  -err- true  -err- false |true  true  true  true  false false
F=   : false true  -err- true  -err- false |true  true  true  true  false false
T!=  : true  true  -err- true  -err- false |true  true  true  true  false false
F!=  : false true  -err- true  -err- false |true  true  true  true  false false
Teq  : true  true  -err- true  -err- false |true  true  true  true  false false
Feq  : false true  -err- true  -err- false |true  true  true  true  false false
Tne  : true  true  -err- true  -err- false |true  true  true  true  false false
Fne  : false true  -err- true  -err- false |true  true  true  true  false false

Wenn Sie wissen möchten, ob eine Variable eine Länge ungleich Null hat, führen Sie einen der folgenden Schritte aus:

  • zitieren Sie die Variable in einzelnen Klammern (Spalte 2a)
  • Verwenden Sie -n und zitieren Sie die Variable in einzelnen Klammern (Spalte 4a)
  • Verwenden Sie doppelte Klammern mit oder ohne Anführungszeichen und mit oder ohne -n (Spalten 1b - 4b)

Beachten Sie in Spalte 1a beginnend bei der Zeile mit der Bezeichnung "two", dass das Ergebnis anzeigt, dass [ den Inhalt der Variablen so bewertet, als ob sie Teil des Bedingungsausdrucks wären (das Ergebnis stimmt mit der durch "T" oder "F" implizierten Behauptung überein) in der Beschreibungsspalte). Wenn [[ wird verwendet (Spalte 1b), wird der Inhalt der Variablen als String angesehen und nicht ausgewertet.

Die Fehler in den Spalten 3a und 5a werden durch die Tatsache verursacht, dass der Variablenwert ein Leerzeichen enthält und die Variable nicht in Anführungszeichen steht. Wie in den Spalten 3b und 5b gezeigt, wertet [[ den Inhalt der Variablen als String aus.

Wenn Sie [ , wird die Variable zitiert, um sicherzustellen, dass Sie keine unerwarteten Ergebnisse erhalten. Mit [[ ist es egal.

Die Fehlermeldungen, die unterdrückt werden, sind "unärer Operator erwartet" oder "binärer Operator erwartet".

Dies ist das Skript, das die obige Tabelle erstellt hat.

#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://.com/questions/3869072/test-for-non-zero-length-string-in-bash-n-var-or-var
# designed to fit an 80 character terminal

dw=5    # description column width
w=6     # table column width

t () { printf "%-${w}s" "true"; }
f () { [[ $? == 1 ]] && printf "%-${w}s" "false " || printf "%-${w}s" "-err- "; }

o=/dev/null

echo '       1a    2a    3a    4a    5a    6a    |1b    2b    3b    4b    5b    6b'
echo '       [     ["    [-n   [-n"  [-z   [-z"  |[[    [["   [[-n  [[-n" [[-z  [[-z"'

while read -r d t
do
    printf "%-${dw}s: " "$d"

    case $d in
        unset) unset t  ;;
        space) t=' '    ;;
    esac

    [ $t ]        2>$o  && t || f
    [ "$t" ]            && t || f
    [ -n $t ]     2>$o  && t || f
    [ -n "$t" ]         && t || f
    [ -z $t ]     2>$o  && t || f
    [ -z "$t" ]         && t || f
    echo -n "|"
    [[ $t ]]            && t || f
    [[ "$t" ]]          && t || f
    [[ -n $t ]]         && t || f
    [[ -n "$t" ]]       && t || f
    [[ -z $t ]]         && t || f
    [[ -z "$t" ]]       && t || f
    echo

done <<'EOF'
unset
null
space
zero    0
digit   1
char    c
hyphn   -z
two     a b
part    a -a
Tstr    -n a
Fsym    -h .
T=      1 = 1
F=      1 = 2
T!=     1 != 2
F!=     1 != 1
Teq     1 -eq 1
Feq     1 -eq 2
Tne     1 -ne 2
Fne     1 -ne 1
EOF

Hier sind einige weitere Tests

True, wenn die Zeichenfolge nicht leer ist:

[ -n "$var" ]
[[ -n $var ]]
test -n "$var"
[ "$var" ]
[[ $var ]]
(( ${#var} ))
let ${#var}
test "$var"

True, wenn die Zeichenfolge leer ist:

[ -z "$var" ]
[[ -z $var ]]
test -z "$var"
! [ "$var" ]
! [[ $var ]]
! (( ${#var} ))
! let ${#var}
! test "$var"




if-statement