При написании сценариев я обычно пишу свои if со следующим синтаксисом, так как мне легче понять, что то, что будет дальше, не соответствует действительности.
if [ ! "$1" = "$2" ]; then
Другие говорят, что путь ниже лучше
if [ "$1" != "$2" ]; then
Дело в том, что когда я спрашиваю, почему и есть ли различия, никто, похоже, не может ответить.
Итак, есть ли различия между двумя синтаксисами? Один из них безопаснее другого? Или это просто вопрос предпочтений / привычки?
!(x==y)
от(!x)==y
.if [ ! "$string" = "one" ]
переводит, если не значение$string
равноone
. И этоif [ "$string" != "one"]
означает, что значение$string
не равноone
?!=
синтаксис) просто более очевиден.Ответы:
Помимо косметических аргументов / аргументов предпочтения, одной из причин может быть то, что существует больше реализаций, где
[ ! "$a" = "$b" ]
в угловых случаях происходит сбой, чем в[ "$a" != "$b" ]
.Оба случая должны быть безопасными, если реализации следуют алгоритму POSIX , но даже сегодня (в начале 2018 года на момент написания) все еще существуют реализации, которые терпят неудачу. Например, с
a='(' b=')'
:В
dash
версиях до 0.5.9, таких как 0.5.8, какsh
в Ubuntu 16.04, например:(исправлено в 0.5.9, см. https://www.mail-archive.com/dash@vger.kernel.org/msg00911.html )
Эти реализации обрабатываются
[ ! "(" = ")" ]
следующим образом (проверяют[ ! "(" "text" ")" ]
, является[ ! "text" ]
ли «текст» пустой строкой), в то время как POSIX предписывает это[ ! "x" = "y" ]
(проверяет «x» и «y» на равенство). Эти реализации терпят неудачу, потому что они выполняют неправильный тест в этом случае.Обратите внимание, что есть еще одна форма:
Для этого требуется оболочка POSIX (не будет работать со старой оболочкой Bourne).
Обратите внимание, что в нескольких реализациях также были проблемы с
[ "$a" = "$b" ]
(и[ "$a" != "$b" ]
), и они по-прежнему похожи на[
встроенные в/bin/sh
Solaris 10 (оболочка Bourne, в которой находится оболочка POSIX/usr/xpg4/bin/sh
). Вот почему вы видите такие вещи, как:В скриптах стараюсь быть переносимым на старые системы.
источник
! "$a" = "b"
вами нужно быть более внимательным к тому, как вы пишете его, чтобы определить сравнение. Из вашего примера я понимаю, что возвращается вторая команда,not zero
которая может быть как полезной, так и тревожной. Это может быть полезно, если вы хотите выйти, если они не совпадают, или беспокоиться, если вы хотите увидеть, не сработало ли сравнение[ ! "$a" = "$b" ]
просто происходит сбой, когда$a
есть(
и$b
есть)
, он утверждает, что они идентичны, когда они не совпадают, не(
является той же строкой, что и)
, но[
в этом случае выполняет неправильный тест.[ ! "$a" = "$b" ]
иногда неправильно обрабатывается в ошибочных реализациях оболочки (которые, я думаю, более или менее повторяют первое предложение ответа).x != y
Синтаксис лучше , потому что! x == y
это чревата ошибки - требует знаний операторов старшинства , которые отличаются от языка к языку. Синтаксис! x == y
может быть истолковано как!(x == y)
или(!x) == y
, в зависимости от приоритета!
против=
.Например, в
c++
отрицании!
предшествует оператор сравнения / реляции==
, отсюда следующий код:возвращается
Подобное поведение наблюдается во многих других языках, включая, например,
awk
часто используемый инструмент в мире Unix.С другой стороны, сбор операторов вместе с помощью
x != y
не приводит к путанице в качестве устоявшейся модели. Более того, технически говоря,!=
это очень часто не два, а один оператор, поэтому оценка должна быть даже немного быстрее, чем отдельное сравнение, а затем отрицание. Следовательно, хотя оба синтаксиса работают в bash, я бы порекомендовал следовать, такx != y
как это намного легче читать и поддерживать код, который следует некоторой стандартной логике.источник
Такого рода вещи очень на основе мнений, как «ответ» очень сильно зависит от пути мозг индивида , случается быть подключен. Хотя это верно, что семантически,
NOT ( A == B )
идентично(A != B )
, один может быть яснее одному человеку , а другой к другому. Это также зависит от контекста. Например, если у меня установлен флаг, значения могут быть более понятными с одним синтаксисом над другим:в отличие от
источник
if ( FS_OPEN != fileHandleStatus )
в результате простоты случайного набора текста=
вместо того, чтобы==
в языках, где первый - это присвоение, а более поздний тест на равенство (как C) ...