Myślę, że odpowiedź jesteś po zakłada się (jeśli nie zaznaczono) przez Vinko „s odpowiedź , choć nie jest to napisane wprost. Aby rozróżnić, czy WARIANCJA jest ustawiona, ale pusta, czy nie, możesz użyć:
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
Prawdopodobnie możesz połączyć dwa testy w drugiej linii w jeden z:
if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
Jeśli jednak przeczytasz dokumentację Autoconf, zauważysz, że nie zalecają łączenia terminów z „ -a” i zalecają używanie oddzielnych prostych testów połączonych z &&. Nie spotkałem systemu, w którym jest problem; to nie znaczy, że kiedyś nie istniały (ale prawdopodobnie są obecnie niezwykle rzadkie, nawet jeśli nie były tak rzadkie w odległej przeszłości).
Szczegóły tych i innych powiązanych rozszerzeń parametrów powłoki , polecenia testlub[ oraz wyrażeń warunkowych można znaleźć w podręczniku Bash.
Niedawno zostałem zapytany przez e-mail o tę odpowiedź z pytaniem:
Używasz dwóch testów i dobrze rozumiem drugi, ale nie pierwszy. Dokładniej, nie rozumiem potrzeby rozwijania zmiennych
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
Czy to nie przyniesie tego samego?
if [ -z "${VAR}" ]; then echo VAR is not set at all; fi
Uczciwe pytanie - odpowiedź brzmi: „Nie, Twoja prostsza alternatywa nie daje tego samego”.
Załóżmy, że napiszę to przed twoim testem:
VAR=
Twój test powie „WARIANCJA nie jest w ogóle ustawiona”, ale moja powie (przez domniemanie, ponieważ nic nie powtarza) „WARIANCJA jest ustawiona, ale jej wartość może być pusta”. Wypróbuj ten skrypt:
(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo JL:1 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:1 VAR is not set at all; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo JL:2 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:2 VAR is not set at all; fi
)
Wynik to:
JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all
W drugiej parze testów zmienna jest ustawiona, ale ma wartość pustą. To jest różnica, którą wprowadzają notacje ${VAR=value}i ${VAR:=value}. To samo dotyczy ${VAR-value}i ${VAR:-value}, i ${VAR+value}i ${VAR:+value}, i tak dalej.
Jak wskazuje Gili w swojej odpowiedzi , jeśli uruchomisz bashtę set -o nounsetopcję, podstawowa odpowiedź powyżej zawodzi unbound variable. Można to łatwo naprawić:
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
Lub możesz anulować set -o nounsetopcję za pomocą set +u( set -ubędącego odpowiednikiem set -o nounset).