Jak sprawdzić, czy zmienna jest pusta w Bash

Odpowiedzi:

383

W Bash przynajmniej następujące polecenie sprawdza, czy $ var jest pusty :

if [[ -z "$var" ]]; then
   # Do what you want
fi

Polecenie man testjest twoim przyjacielem.

Sójka
źródło
62
podwójne nawiasy kwadratowe są tutaj bezużyteczne. może to być proste [-z „$ var”] lub nawet łatwiejsze imho, jeśli test -z „var” .. w każdym razie +1 :)
Luca Borrione
2
podwójne nawiasy kwadratowe nie są bezużyteczne, jeśli nie mówię, nie mam ./test.ksh[8]: test: argument expectedpowodu, ale pojedynczy nawias nie działał, ale miał go podwójny.
gahlot.jaggs
8
@LucaBorrione Myślę, że masz na myśli if test -z "$var", prawda?
neu242
1
Tylko dodany komentarz do konkretnej sytuacji, nie wymieniony bezpośrednio w pytaniu: jeśli zmienna jest rozbrojona, a set -uopcja została aktywowana, test zakończy się niepowodzeniem unbound variable. W takim przypadku możesz preferować rozwiązanie @ alexli.
anol
3
@LucaBorrione Tak jak ostatnia uwaga: „[[” można uznać za „nigdy bezużyteczne”; ponieważ używanie „[[” ma pewne zalety w stosunku do „[” (patrz na przykład stackoverflow.com/questions/669452/… )
GhostCat
107

Zakładając Bash:

var=""

if [ -n "$var" ]; then
    echo "not empty"
else
    echo "empty"
fi
ChristopheD
źródło
9
Bardziej bezpośrednia odpowiedź brzmi -z:[[ -z "$an_unset_or_empty_var" ]] && echo empty
glenn jackman
4
@glenn jackman: dobry komentarz; to prawda, że -zjest bliżej tego, o co pytano. Jay umieścił to w swojej odpowiedzi, więc powstrzymam się od aktualizacji mojego i pozostawię to bez zmian.
ChristopheD
48

Widziałem też

if [ "x$variable" = "x" ]; then ...

który jest oczywiście bardzo solidny i niezależny od powłoki.

Ponadto istnieje różnica między „pustym” a „nieuzbrojonym”. Zobacz Jak stwierdzić, czy ciąg nie jest zdefiniowany w skrypcie powłoki Bash .

Daniel Andersson
źródło
Wygląda mi dziwnie. Czy możesz wyjaśnić to rozwiązanie. Dziękuję Ci.
guettli,
2
@guettli: Jeśli $variablejest pusty, to ciąg znaków po lewej stronie operatora porównania staje się tylko taki x, który jest równy ciągowi znaków po prawej stronie operatora. [ x = x ]jest „prawdziwe”, więc w praktyce sprawdza się, czy $variablejest pusty, czy nie. Jako dodatek (3 i pół roku po fakcie :-)) Nigdy bym tego nie użył, ponieważ -zrobi to, co prawdopodobnie chcę w jaśniejszy sposób, ale chciałem dodać tę odpowiedź, ponieważ ta metoda jest często postrzegana „na wolności”; być może napisane w ten sposób celowo przez ludzi, którzy mieli inne doświadczenia niż ja.
Daniel Andersson,
30
if [ ${foo:+1} ]
then
    echo "yes"
fi

wypisuje, yesjeśli zmienna jest ustawiona. ${foo:+1}zwróci 1, gdy zmienna jest ustawiona, w przeciwnym razie zwróci pusty ciąg.

alexli
źródło
2
Chociaż nie wspomniano w pytaniu, ważną zaletą tej odpowiedzi jest to, że działa ona nawet wtedy, gdy zmienna jest niezdefiniowana i aktywowana jest set -uopcja ( nounset). unbound variableW tym przypadku prawie wszystkie inne odpowiedzi na to pytanie zawiodą .
anol
:+Notacja ta jest również przydatna w sytuacjach, gdy masz opcjonalne parametry wiersza poleceń, które określiłeś za pomocą opcjonalnych zmiennych. myprogram ${INFILE:+--in=$INFILE} ${OUTFILE:+--out=$OUTFILE}
Alan Porter
10
if [[ "$variable" == "" ]] ...
Amardeep AC9MF
źródło
10
[ "$variable" ] || echo empty
: ${variable="value_to_set_if_unset"}
pixelbeat
źródło
Świetny sposób na domyślną
zmianę
@ehime, aby ustawić wartość domyślną, której byś użył${variable:-default_value}
warvariuc
Jest to szybki sposób sprawdzenia poprawności wpisu zmiennej i wyjścia, jeśli nie jest ustawiony: [ "$variable" ] || exit
Marcel Sonderegger
8

Zwróci to, truejeśli zmienna jest rozbrojona lub ustawiona na pusty ciąg („”).

if [ -z "$MyVar" ]
then
   echo "The variable MyVar has nothing in it."
elif ! [ -z "$MyVar" ]
then
   echo "The variable MyVar has something in it."
fi
3kstc
źródło
3
Dlaczego miałbyś używać elif !zamiast else?
ZiggyTheHamster
1
Wystarczy dokonać rozróżnienia pomiędzy dwoma sprawozdania, czyli używając ! [ -z "$MyVar" ]oznaczałoby, że zmienna będzie mieć coś w nim. Ale idealnie byłoby użyć else.
3kstc
6

Pytanie pyta , jak sprawdzić, czy zmienna jest pusty ciąg znaków i najlepsze odpowiedzi są już podane do tego.

Ale wylądowałem tutaj po pewnym czasie programowania w PHP i szukałem czeku, takiego jak pusta funkcja w PHP pracująca w powłoce Bash.

Po przeczytaniu odpowiedzi zdałem sobie sprawę, że nie myślę poprawnie w Bash, ale w tym momencie funkcja pusta w PHP byłaby bardzo przydatna w moim kodzie Bash.

Ponieważ myślę, że może się to zdarzyć innym, postanowiłem przekonwertować pustą funkcję PHP w Bash.

Zgodnie z instrukcją PHP :

zmienna jest uważana za pustą, jeśli nie istnieje lub jej wartość jest jedną z poniższych:

  • „” (pusty ciąg)
  • 0 (0 jako liczba całkowita)
  • 0,0 (0 jako liczba zmiennoprzecinkowa)
  • „0” (0 jako ciąg)
  • pusta tablica
  • zmienna zadeklarowana, ale bez wartości

Oczywiście przypadków zerowych i fałszywych nie można przekonwertować na bash, więc są one pomijane.

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 "" ) ]]
}



Przykład użycia:

if empty "${var}"
    then
        echo "empty"
    else
        echo "not empty"
fi



Demo:
następujący fragment kodu:

#!/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

wyjścia:

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

Powiedziawszy, że w logice Basha kontrole zerowe w tej funkcji mogą powodować problemy uboczne, imho, każdy korzystający z tej funkcji powinien ocenić to ryzyko i być może zdecydować o ich odcięciu, pozostawiając tylko pierwszą.

Luca Borrione
źródło
2

Możesz rozróżnić zmienne nieustawione od zmiennych, które są ustawione i puste:

is_empty() {
    local var_name="$1"
    local var_value="${!var_name}"
    if [[ -v "$var_name" ]]; then
       if [[ -n "$var_value" ]]; then
         echo "set and non-empty"
       else
         echo "set and empty"
       fi
    else
       echo "unset"
    fi
}

str="foo"
empty=""
is_empty str
is_empty empty
is_empty none

Wynik:

set and non-empty
set and empty
unset

BTW, zalecam użycie, set -uktóre spowoduje błąd podczas odczytu nieuzbrojonych zmiennych, może to uchronić Cię przed katastrofami, takimi jak

rm -rf $dir

Możesz przeczytać o tym i innych najlepszych praktykach dotyczących „trybu ścisłego” tutaj .

dimid
źródło
Dzięki za odniesienie do trybu ścisłego!
paulcm
1

Aby sprawdzić, czy zmienna v nie jest ustawiona

if [ "$v" == "" ]; then
   echo "v not set"
fi
smishra
źródło