Czy to obejmuje, jeśli zmienną ustawiono na wartość „”?
Brent
11
Tak, robi… Test „-z” dla łańcucha o zerowej długości.
David Z
91
if [ ! -z "$VAR" ];
Aaron Copley,
263
odwrotnością -zjest-nif [ -n "$VAR" ];
Felipe Alvarez
19
Podwójne cudzysłowy zapewniają, że zmienna nie zostanie podzielona. Prosta $varw wierszu polecenia zostanie podzielona przez jego biały znak na listę parametrów, a "$var"zawsze będzie tylko jednym parametrem. Cytowanie zmiennych często jest dobrą praktyką i powstrzymuje cię przed potknięciem się o nazwy plików zawierające spacje (między innymi). Przykład: po zrobieniu a="x --help"spróbuj cat $a- wyświetli się strona pomocy dla cat. Następnie spróbuj cat "$a"- to (zwykle) powie cat: x --help: No such file or directory. Krótko mówiąc, cytuj wcześnie i cytuj często, a prawie nigdy nie będziesz żałować.
Score_Under
247
W Bash, gdy nie martwisz się o przenośność do powłok, które go nie obsługują, powinieneś zawsze używać składni podwójnego nawiasu:
W Bash, używając podwójnych nawiasów kwadratowych, cudzysłowy nie są konieczne. Możesz uprościć test dla zmiennej, która zawiera wartość:
if[[ $variable ]]
Ta składnia jest kompatybilna z ksh (przynajmniej ksh93, w każdym razie). Nie działa w czystym POSIX-ie lub starszych powłokach Bourne'a, takich jak sh lub dash.
Zobacz moją odpowiedź tutaj i BashFAQ / 031, aby uzyskać więcej informacji na temat różnic między nawiasami kwadratowymi podwójnymi i pojedynczymi.
Możesz sprawdzić, czy zmienna jest konkretnie nieuzbrojona (w odróżnieniu od pustego ciągu):
if[[-z ${variable+x}]]
gdzie „x” jest dowolne.
Jeśli chcesz wiedzieć, czy zmienna ma wartość NULL, ale nie jest rozbrojona:
To if [[ $variable ]]działało dobrze dla mnie i nawet nie potrzebowało tego, set -uco było wymagane przez jedno z innych proponowanych rozwiązań.
Teemu Leisti,
3
Myślę, że to lepsze niż zaakceptowana odpowiedź.
qed
2
Dlaczego polecasz funkcję nieprzenośną, jeśli nie przynosi to żadnych korzyści?
Alastair Irvine
19
@AlastairIrvine: Wspominam o przenośności w pierwszym zdaniu mojej odpowiedzi, tytuł pytania i treść zawierają słowo „Bash”, a pytanie jest oznaczone jako bash , a struktura podwójnego nawiasu zapewnia wyraźne zalety na wiele sposobów. I nie polecam mieszania stylów wsporników ze względu na spójność i łatwość konserwacji. Jeśli potrzebujesz maksymalnej, najniższej przenośności wspólnego mianownika, użyj shzamiast Bash. Jeśli potrzebujesz zwiększonych możliwości, które zapewnia, użyj Bash i wykorzystaj go w pełni.
Dennis Williamson
2
@BrunoBronosky: Cofnąłem edycję. Na ;koniec nie ma wymogu . thenMoże być w następnym wierszu bez średnikiem w ogóle.
Dennis Williamson
230
Zmienna w bash (i dowolnej powłoce kompatybilnej z POSIX) może znajdować się w jednym z trzech stanów:
nieoprawny
ustawiony na pusty ciąg
ustawiony na niepusty ciąg
Przez większość czasu musisz tylko wiedzieć, czy zmienna jest ustawiona na niepusty ciąg, ale czasami ważne jest, aby odróżnić unset od ustawionego na pusty ciąg.
Oto przykłady tego, jak możesz przetestować różne możliwości i działa on w bash lub dowolnej powłoce kompatybilnej z POSIX:
if[-z "${VAR}"];then
echo "VAR is unset or set to the empty string"fiif[-z "${VAR+set}"];then
echo "VAR is unset"fiif[-z "${VAR-unset}"];then
echo "VAR is set to the empty string"fiif[-n "${VAR}"];then
echo "VAR is set to a non-empty string"fiif[-n "${VAR+set}"];then
echo "VAR is set, possibly to the empty string"fiif[-n "${VAR-unset}"];then
echo "VAR is either unset or set to a non-empty string"fi
${VAR+foo}Konstrukt rozwija do pustego ciągu znaków, jeśli VARjest wyłączony lub foojeśli VARjest ustawiony na cokolwiek (w tym ciąg pusty).
${VAR-foo}Konstrukcja zwiększa się do wartości VAR, jeśli zestaw (obejmującą łańcuch pusty), a foojeśli ustawiony. Jest to przydatne do zapewnienia domyślnych ustawień nadpisywanych przez użytkownika (np. ${COLOR-red}Mówi, aby używać, redchyba że zmienna COLORzostała ustawiona na coś).
Powodem, dla którego [ x"${VAR}" = x ]często zaleca się testowanie, czy zmienna jest nieuzbrojona, czy ustawiona na pusty ciąg, jest to, że niektóre implementacje [polecenia (znane również jako test) są błędne. Jeśli VARjest ustawiony na coś podobnego -n, wówczas niektóre implementacje zrobią coś złego, gdy podano, [ "${VAR}" = "" ]ponieważ pierwszy argument do [jest błędnie interpretowany jako -noperator, a nie ciąg.
Testowanie zmiennej ustawionej na pusty ciąg można również wykonać za pomocą [ -z "${VAR-set}" ].
nwellnhof
@nwellnhof: Dzięki! Zaktualizowałem swoją odpowiedź, aby użyć składni briefer.
Richard Hansen
Jaka jest różnica między pierwszym a ostatnim konstruktem? Oba odpowiadają „VAR jest albo rozbrojony, albo ustawiony na niepusty ciąg”.
Faheem Mitha,
1
@FaheemMitha: To nie twoja wina - moja odpowiedź była trudna do odczytania. Dodałem tabelę, aby, mam nadzieję, wyjaśnić odpowiedź.
Richard Hansen
2
Nieuzbrojone kontrole nie są wiarygodne. Jeśli użytkownik zadzwoni set -ulub uruchomi set -o nounsetbash, wówczas test spowoduje błąd „bash: VAR: zmienna niezwiązana”. Zobacz stackoverflow.com/a/13864829, aby uzyskać bardziej niezawodne sprawdzanie rozbrojenia. Moje przejście do sprawdzenia, czy zmienna ma wartość NULL czy nie jest ustawione [ -z "${VAR:-}" ]. Sprawdzam, czy zmienna nie jest pusta [ "${VAR:-}" ].
Kevin Jin,
38
-z to najlepszy sposób.
Inną opcją, której użyłem, jest ustawienie zmiennej, ale można ją zastąpić inną zmienną, np
export PORT=${MY_PORT:-5432}
Jeśli $MY_PORTzmienna jest pusta, PORTzostaje ustawiona na 5432, w przeciwnym razie PORT jest ustawiony na wartość MY_PORT. Uwaga: składnia obejmuje dwukropek i myślnik.
Alternatywą, którą widziałem, [ -z "$foo" ]jest następująca, jednak nie jestem pewien, dlaczego ludzie używają tej metody, ktoś wie?
["x${foo}"="x"]
W każdym razie, jeśli nie zezwalasz na nieuzbrojone zmienne (przez set -ulub set -o nounset), wtedy będziesz mieć problemy z obiema tymi metodami. Jest na to prosta poprawka:
Jest to komentarz na temat alternatywy dla -zw pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . Zasadniczo nie jest to alternatywa dla -z. Raczej obsługuje przypadki, w których $foomoże rozwinąć się do czegoś zaczynającego się od metaznaku, który mógłby [lub testbyłby w stanie pomylić. Umieszczenie na początku dowolnego metaznaku eliminuje tę możliwość.
James Sneeringer,
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, a tym, czego tak naprawdę szukałem, było sprawdzenie, jak pusta funkcja w php działają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ć funkcję pustego php w bash
Zgodnie z instrukcją php : zmienna jest uważana za pustą, jeśli nie istnieje lub jeśli jej wartość jest jedną z następujących:
„” (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 passedif test -z "$var"then[[ $( echo "1")]]return# Return true if var is zero (0 as an integer or "0" as a string)elif["$var"==02>/dev/null ]then[[ $( echo "1")]]return# Return true if var is 0.0 (0 as a float)elif["$var"==0.02>/dev/null ]then[[ $( echo "1")]]returnfi[[ $( echo "")]]}
Przykład użycia:
if empty "${var}"then
echo "empty"else
echo "not empty"fi
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 bash 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ć się odciąć te kontrole, pozostawiając tylko pierwszą.
To się nie powiedzie, jeśli foo zawiera tylko spacje
Brian
2
Nie powiedzie się również w niektórych powłokach, jeśli foo zaczyna się od myślnika, ponieważ jest interpretowane jako opcja. Np. Na solarisach ksh , zsh i bash nie stanowią problemu, sh i / bin / test się nie
udadzą
4
Dzieje się tak dokładnie wtedy, gdy $ FOO jest ustawione i puste:
Niektóre pociski nie akceptują podwójnego znaku równości.
Dennis Williamson,
1
Pytanie dotyczyło bashu. Używam bash. Działa dla mnie dobrze. O czym dokładnie mówisz?
Fedir RYKHTIK
2
Jeśli używasz Bash, powinieneś użyć podwójnych nawiasów kwadratowych. Mój poprzedni komentarz był prostym stwierdzeniem dla tych, którzy mogą przeczytać twoją odpowiedź i używać innej powłoki.
Moje 5 centów: istnieje również krótsza składnia niż if ...ta:
VALUE="${1?"Usage: $0 value"}"
Ten wiersz ustawi WARTOŚĆ, jeśli podany zostanie argument, i wyświetli komunikat o błędzie poprzedzony numerem wiersza skryptu w przypadku błędu (i zakończy wykonywanie skryptu).
Kolejny przykład można znaleźć w przewodniku abs (wyszukaj „Przykład 10-7”).
Nie jest to dokładna odpowiedź, ale wpadłem na tę sztuczkę. Jeśli ciąg, którego szukasz, pochodzi od „polecenia”, możesz faktycznie zapisać polecenie w env. zmienną, a następnie wykonuj ją za każdym razem dla instrukcji if, wtedy nawiasy nie są wymagane!
Na przykład to polecenie, które określa, czy korzystasz z Debiana:
Jest to więc sposób pośredni (ponowne uruchamianie go za każdym razem) w celu sprawdzenia pustego ciągu (zdarza się, że sprawdza odpowiedź na błąd z polecenia, ale zdarza się również, że zwraca pusty ciąg).
Odpowiedzi:
Zwróci wartość true, jeśli zmienna jest rozbrojona lub ustawiona na pusty ciąg („”).
źródło
if [ ! -z "$VAR" ];
-z
jest-n
if [ -n "$VAR" ];
$var
w wierszu polecenia zostanie podzielona przez jego biały znak na listę parametrów, a"$var"
zawsze będzie tylko jednym parametrem. Cytowanie zmiennych często jest dobrą praktyką i powstrzymuje cię przed potknięciem się o nazwy plików zawierające spacje (między innymi). Przykład: po zrobieniua="x --help"
spróbujcat $a
- wyświetli się strona pomocy dlacat
. Następnie spróbujcat "$a"
- to (zwykle) powiecat: x --help: No such file or directory
. Krótko mówiąc, cytuj wcześnie i cytuj często, a prawie nigdy nie będziesz żałować.W Bash, gdy nie martwisz się o przenośność do powłok, które go nie obsługują, powinieneś zawsze używać składni podwójnego nawiasu:
Dowolny z poniższych:
W Bash, używając podwójnych nawiasów kwadratowych, cudzysłowy nie są konieczne. Możesz uprościć test dla zmiennej, która zawiera wartość:
Ta składnia jest kompatybilna z ksh (przynajmniej ksh93, w każdym razie). Nie działa w czystym POSIX-ie lub starszych powłokach Bourne'a, takich jak sh lub dash.
Zobacz moją odpowiedź tutaj i BashFAQ / 031, aby uzyskać więcej informacji na temat różnic między nawiasami kwadratowymi podwójnymi i pojedynczymi.
Możesz sprawdzić, czy zmienna jest konkretnie nieuzbrojona (w odróżnieniu od pustego ciągu):
gdzie „x” jest dowolne.
Jeśli chcesz wiedzieć, czy zmienna ma wartość NULL, ale nie jest rozbrojona:
źródło
if [[ $variable ]]
działało dobrze dla mnie i nawet nie potrzebowało tego,set -u
co było wymagane przez jedno z innych proponowanych rozwiązań.sh
zamiast Bash. Jeśli potrzebujesz zwiększonych możliwości, które zapewnia, użyj Bash i wykorzystaj go w pełni.;
koniec nie ma wymogu .then
Może być w następnym wierszu bez średnikiem w ogóle.Zmienna w bash (i dowolnej powłoce kompatybilnej z POSIX) może znajdować się w jednym z trzech stanów:
Przez większość czasu musisz tylko wiedzieć, czy zmienna jest ustawiona na niepusty ciąg, ale czasami ważne jest, aby odróżnić unset od ustawionego na pusty ciąg.
Oto przykłady tego, jak możesz przetestować różne możliwości i działa on w bash lub dowolnej powłoce kompatybilnej z POSIX:
Oto to samo, ale w poręcznej formie tabeli:
${VAR+foo}
Konstrukt rozwija do pustego ciągu znaków, jeśliVAR
jest wyłączony lubfoo
jeśliVAR
jest ustawiony na cokolwiek (w tym ciąg pusty).${VAR-foo}
Konstrukcja zwiększa się do wartościVAR
, jeśli zestaw (obejmującą łańcuch pusty), afoo
jeśli ustawiony. Jest to przydatne do zapewnienia domyślnych ustawień nadpisywanych przez użytkownika (np.${COLOR-red}
Mówi, aby używać,red
chyba że zmiennaCOLOR
została ustawiona na coś).Powodem, dla którego
[ x"${VAR}" = x ]
często zaleca się testowanie, czy zmienna jest nieuzbrojona, czy ustawiona na pusty ciąg, jest to, że niektóre implementacje[
polecenia (znane również jakotest
) są błędne. JeśliVAR
jest ustawiony na coś podobnego-n
, wówczas niektóre implementacje zrobią coś złego, gdy podano,[ "${VAR}" = "" ]
ponieważ pierwszy argument do[
jest błędnie interpretowany jako-n
operator, a nie ciąg.źródło
[ -z "${VAR-set}" ]
.set -u
lub uruchomiset -o nounset
bash, wówczas test spowoduje błąd „bash: VAR: zmienna niezwiązana”. Zobacz stackoverflow.com/a/13864829, aby uzyskać bardziej niezawodne sprawdzanie rozbrojenia. Moje przejście do sprawdzenia, czy zmienna ma wartość NULL czy nie jest ustawione[ -z "${VAR:-}" ]
. Sprawdzam, czy zmienna nie jest pusta[ "${VAR:-}" ]
.-z
to najlepszy sposób.Inną opcją, której użyłem, jest ustawienie zmiennej, ale można ją zastąpić inną zmienną, np
Jeśli
$MY_PORT
zmienna jest pusta,PORT
zostaje ustawiona na 5432, w przeciwnym razie PORT jest ustawiony na wartośćMY_PORT
. Uwaga: składnia obejmuje dwukropek i myślnik.źródło
set -o nounset
niektóre skrypty.Jeśli chcesz rozróżnić przypadki ustawiania pustego w porównaniu ze statusem nieustawionym, spójrz na opcję -u dla bash:
źródło
Alternatywą, którą widziałem,
[ -z "$foo" ]
jest następująca, jednak nie jestem pewien, dlaczego ludzie używają tej metody, ktoś wie?W każdym razie, jeśli nie zezwalasz na nieuzbrojone zmienne (przez
set -u
lubset -o nounset
), wtedy będziesz mieć problemy z obiema tymi metodami. Jest na to prosta poprawka:Uwaga: pozostawi zmienną niezdefiniowaną.
źródło
-z
w pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . Zasadniczo nie jest to alternatywa dla-z
. Raczej obsługuje przypadki, w których$foo
może rozwinąć się do czegoś zaczynającego się od metaznaku, który mógłby[
lubtest
byłby w stanie pomylić. Umieszczenie na początku dowolnego metaznaku eliminuje tę możliwość.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, a tym, czego tak naprawdę szukałem, było sprawdzenie, jak pusta funkcja w php działają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ć funkcję pustego php w bash
Zgodnie z instrukcją php :
zmienna jest uważana za pustą, jeśli nie istnieje lub jeśli jej wartość jest jedną z następujących:
Oczywiście przypadków zerowych i fałszywych nie można przekonwertować na bash, więc są one pomijane.
Przykład użycia:
Demo:
następujący fragment:
wyjścia:
Powiedziawszy, że w logice bash 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ć się odciąć te kontrole, pozostawiając tylko pierwszą.
źródło
empty
- dlaczego napisałeś[[ $( echo "1" ) ]] ; return
zamiast po prostureturn 1
?całe if-then i -z są niepotrzebne.
źródło
Dzieje się tak dokładnie wtedy, gdy $ FOO jest ustawione i puste:
źródło
Osobiście wolę bardziej przejrzysty sposób sprawdzenia:
źródło
rozszerzenie oneliner rozwiązania duffbeer703 :
źródło
Moje 5 centów: istnieje również krótsza składnia niż
if ...
ta:Ten wiersz ustawi WARTOŚĆ, jeśli podany zostanie argument, i wyświetli komunikat o błędzie poprzedzony numerem wiersza skryptu w przypadku błędu (i zakończy wykonywanie skryptu).
Kolejny przykład można znaleźć w przewodniku abs (wyszukaj „Przykład 10-7”).
źródło
Nie jest to dokładna odpowiedź, ale wpadłem na tę sztuczkę. Jeśli ciąg, którego szukasz, pochodzi od „polecenia”, możesz faktycznie zapisać polecenie w env. zmienną, a następnie wykonuj ją za każdym razem dla instrukcji if, wtedy nawiasy nie są wymagane!
Na przykład to polecenie, które określa, czy korzystasz z Debiana:
grep debian /proc/version
pełny przykład:
Jest to więc sposób pośredni (ponowne uruchamianie go za każdym razem) w celu sprawdzenia pustego ciągu (zdarza się, że sprawdza odpowiedź na błąd z polecenia, ale zdarza się również, że zwraca pusty ciąg).
źródło