Odpowiedzi:
Zwróci wartość true, jeśli zmienna jest rozbrojona lub ustawiona na pusty ciąg („”).
if [ -z "$VAR" ];
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 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ć.
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:
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
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:
if [[ -z $variable && ${variable+x} ]]
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:
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
Oto to samo, ale w poręcznej formie tabeli:
+-------+-------+-----------+
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 |
+-----------------------+-------+-------+-----------+
${VAR+foo}
Konstrukt rozwija do pustego ciągu znaków, jeśli VAR
jest wyłączony lub foo
jeśli VAR
jest 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 foo
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 zmienna COLOR
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ż jako test
) są błędne. Jeśli VAR
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.
[ -z "${VAR-set}" ]
.
set -u
lub uruchomi set -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
export PORT=${MY_PORT:-5432}
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.
set -o nounset
niektóre skrypty.
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 -u
lub set -o nounset
), wtedy będziesz mieć problemy z obiema tymi metodami. Jest na to prosta poprawka:
[ -z "${foo:-}" ]
Uwaga: pozostawi zmienną niezdefiniowaną.
-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 [
lub test
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.
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:
#!/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 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ą.
empty
- dlaczego napisałeś [[ $( echo "1" ) ]] ; return
zamiast po prostu return 1
?
całe if-then i -z są niepotrzebne.
[„$ foo”] && echo „foo nie jest puste” [„$ foo”] || echo „foo jest rzeczywiście pusty”
Dzieje się tak dokładnie wtedy, gdy $ FOO jest ustawione i puste:
[ "${FOO+x}" = x ] && [ -z "$FOO" ]
Osobiście wolę bardziej przejrzysty sposób sprawdzenia:
if [ "${VARIABLE}" == "" ]; then
echo VARIABLE is empty
else
echo VARIABLE is not empty
fi
rozszerzenie oneliner rozwiązania duffbeer703 :
#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
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:
grep debian /proc/version
pełny przykład:
IS_DEBIAN="grep -i debian /proc/version"
if $IS_DEBIAN; then
echo 'yes debian'
else
echo 'non debian'
fi
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).