Oprócz argumentów kosmetycznych / preferencji, jednym z powodów może być to, że jest więcej implementacji, w których [ ! "$a" = "$b" ]
zawodzi się w przypadkach narożnych niż z [ "$a" != "$b" ]
.
Oba przypadki powinny być bezpieczne, jeśli implementacje są zgodne z algorytmem POSIX , ale nawet dzisiaj (na początku 2018 r. W momencie pisania) nadal istnieją implementacje, które zawodzą. Na przykład z a='(' b=')'
:
$ (a='(' b=')'; busybox test "$a" != "$b"; echo "$?")
0
$ (a='(' b=')'; busybox test ! "$a" = "$b"; echo "$?")
1
Na przykład w dash
wersjach wcześniejszych niż 0.5.9, takich jak 0.5.8, jak sh
na przykład Ubuntu 16.04:
$ a='(' b=')' dash -c '[ "$a" != "$b" ]; echo "$?"'
0
$ a='(' b=')' dash -c '[ ! "$a" = "$b" ]; echo "$?"'
1
(naprawiony w wersji 0.5.9, patrz https://www.mail-archive.com/dash@vger.kernel.org/msg00911.html )
Te implementacje traktują [ ! "(" = ")" ]
tak [ ! "(" "text" ")" ]
, jak jest [ ! "text" ]
(sprawdź, czy „tekst” jest łańcuchem pustym), podczas gdy POSIX tak nakazuje [ ! "x" = "y" ]
(przetestuj „x” i „y” pod kątem równości). Te implementacje kończą się niepowodzeniem, ponieważ w tym przypadku wykonują zły test.
Pamiętaj, że istnieje jeszcze jedna forma:
! [ "$a" = "$b" ]
Ten wymaga powłoki POSIX (nie będzie działać ze starą powłoką Bourne'a).
Zauważ, że kilka implementacji miało również problemy z [ "$a" = "$b" ]
(i [ "$a" != "$b" ]
) i nadal działa podobnie jak [
wbudowane /bin/sh
w Solaris 10 (powłoka Bourne'a, w której znajduje się powłoka POSIX /usr/xpg4/bin/sh
). Dlatego widzisz takie rzeczy jak:
[ "x$a" != "x$b" ]
W skryptach próbuje być przenośny na stare systemy.
!(x==y)
od(!x)==y
.