Окрім косметичних аргументів / переваг, однією з причин може бути те, що існує більше реалізацій, де [ ! "$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" ]
(тест «х» і «у» рівності). Ці реалізації не вдається, оскільки вони виконують неправильний тест у такому випадку.
Зауважте, що існує ще одна форма:
! [ "$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
.