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 test
lub[
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 bash
tę set -o nounset
opcję, 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 nounset
opcję za pomocą set +u
( set -u
będącego odpowiednikiem set -o nounset
).