Помимо косметических аргументов / аргументов предпочтения, одной из причин может быть то, что существует больше реализаций, где [ ! "$a" = "$b" ]
в угловых случаях происходит сбой, чем в [ "$a" != "$b" ]
.
Оба случая должны быть безопасными, если реализации следуют алгоритму POSIX , но даже сегодня (в начале 2018 года на момент написания) все еще существуют реализации, которые терпят неудачу. Например, с a='(' b=')'
:
$ (a='(' b=')'; busybox test "$a" != "$b"; echo "$?")
0
$ (a='(' b=')'; busybox test ! "$a" = "$b"; echo "$?")
1
В dash
версиях до 0.5.9, таких как 0.5.8, как sh
в Ubuntu 16.04, например:
$ a='(' b=')' dash -c '[ "$a" != "$b" ]; echo "$?"'
0
$ a='(' b=')' dash -c '[ ! "$a" = "$b" ]; echo "$?"'
1
(исправлено в 0.5.9, см. https://www.mail-archive.com/dash@vger.kernel.org/msg00911.html )
Эти реализации обрабатываются [ ! "(" = ")" ]
следующим образом (проверяют [ ! "(" "text" ")" ]
, является [ ! "text" ]
ли «текст» пустой строкой), в то время как POSIX предписывает это [ ! "x" = "y" ]
(проверяет «x» и «y» на равенство). Эти реализации терпят неудачу, потому что они выполняют неправильный тест в этом случае.
Обратите внимание, что есть еще одна форма:
! [ "$a" = "$b" ]
Для этого требуется оболочка POSIX (не будет работать со старой оболочкой Bourne).
Обратите внимание, что в нескольких реализациях также были проблемы с [ "$a" = "$b" ]
(и [ "$a" != "$b" ]
), и они по-прежнему похожи на [
встроенные в /bin/sh
Solaris 10 (оболочка Bourne, в которой находится оболочка POSIX /usr/xpg4/bin/sh
). Вот почему вы видите такие вещи, как:
[ "x$a" != "x$b" ]
В скриптах стараюсь быть переносимым на старые системы.
!(x==y)
от(!x)==y
.