W Bash, czy [-z „$ 1”] i jeśli [„$ 1” = „”] są takie same?

28

Jaka jest różnica (jeśli występuje) w skryptach powłoki Bash między następującymi dwiema instrukcjami?

    1.) if [ -z "$1" ]
    2.) if [ "$1" = "" ]

Znalazłem siebie, pisząc drugi w niektórych skryptach, ale potem przeczytałem tutaj, że używanie -zosiąga to samo.

Jeśli występują problemy z korzystaniem z drugiego, czy należy zignorować, że pierwszy wygląda trochę lepiej?

Johan
źródło
3
Aby uzyskać szczegółowe porównanie, zobacz moją odpowiedź na temat przepełnienia stosu. Zobacz także to i to .
Wstrzymano do odwołania.
ładne linki, z ciekawymi odpowiedziami :)
Johan

Odpowiedzi:

36

[ "$1" = "" ]i [ -z "$1" ]są dokładnie równoważne w bash i innych powłokach zgodnych z POSIX. (Pamiętaj, że po każdej stronie nawiasów musi znajdować się spacja, chyba że występuje znak inny niż składający się na słowo ;.)

[jest powłoką wbudowaną jak każda inna; w rzeczywistości można go także przeliterować test(jedyna różnica między nimi polega na tym, że [wymaga on ]argumentu jako ostatniego argumentu). Więc jeśli uruchomić [ "$1" = "" ]z $1rozszerza się -z, operator testu widzi trzy argumenty: -z, =i pusty łańcuch. Niektóre starsze powłoki Bourne'a czasami rzucały błędy parsowania, gdy operand wyglądał w ten sposób jak operator, nawet jeśli nie było dwuznaczności w pełnym wyrażeniu. Nie wiem, czy jakakolwiek wersja faktycznie miała problemy z tym konkretnym wyrażeniem, ale bardziej złożone wyrażenia mogłyby je zrzucić. Mogą istnieć również wersje, które miały problem z pustymi słowami; te też by nie poparły [ -z "$1" ]. Typowym idiomem powłoki jest[ x"$1" = x"" ]. Pozwala to uniknąć ryzyka parsowania argumentów jako operatorów, ponieważ żaden operator nie zaczyna się na literę.

W ksh, bash i zsh, można użyć składni podwójny wspornik [[ -z $1 ]]. Ta nowsza składnia (pochodzi z późnych lat 80., a nie z połowy lat 70.) eliminuje ryzyko parsowania argumentów jako operatorów, używając specjalnej konstrukcji składniowej zamiast zwykłego wbudowanego. Operatory muszą pojawiać się dosłownie, bez cudzysłowu w podwójnych nawiasach i nie trzeba podwójnie cytować rozszerzeń zmiennych.

Gilles „SO- przestań być zły”
źródło
Naprawiono literówkę z brakującym miejscem obok nawiasu.
Johan