Предпочтительный

Предпочтительный

Есть ли разница в bash или предпочтительное использование отрицания оператора?

if ! [[ -z "${var}" ]]; then
  do_something
fi

Против

if [[ ! -z "${var}" ]]; then
  do_something
fi

решение1

! [[ expression ]]

Это будет верно, если весь тест вернет false.

[[ ! expression ]]

Это будет верно, если отдельное выражение вернет ложь.


Поскольку тест может быть составным выражением, это может быть очень по-разному. Например:

$ [[ ! 0 -eq 1 || 1 -eq 1 ]] && echo yes || echo no
yes
$ ! [[ 0 -eq 1 || 1 -eq 1 ]] && echo yes || echo no
no

Лично я предпочитаю использовать отрицание внутри тестовой конструкции, где это применимо, но и снаружи оно тоже прекрасно подходит, в зависимости от ваших намерений.

решение2

А ! cmdна самом деле этотрубка, и !отрицает код выходавесьтрубка.

Из man bash:

Конвейеры Конвейер — это последовательность из одной или нескольких команд, разделенных одним из операторов управления | или |&. Формат конвейера:

         [time [-p]] [ ! ] command [ [|||&] command2 ... ]

...
Если зарезервированное слово ! предшествует конвейеру, статус выхода этого конвейера является логическим отрицанием статуса выхода, как описано выше. Оболочка ждет завершения всех команд в конвейере, прежде чем возвращать значение.

В этом смысле:

! [[ 2 -eq 2 ]]

Является отрицанием ( !) кода выхода всего [[(после того, как все это было выполнено). Таким образом, это имеет код выхода 0:

!  [[ 2 -eq 2 && 3 -eq 4 ]]

Однако

А [[ ! ]]есть аСоставная команда(не труба). Из man bash:

Составные команды
...
[[ выражение ]]
Возвращают статус 0 или 1 в зависимости от оценки условного выражения выражение.
Выражения состоят из основных элементов, описанных ниже в разделе УСЛОВНЫЕ ВЫРАЖЕНИЯ.

Следовательно, код выхода равен 1:

[[ ! 2 -eq 2 && 3 -eq 4 ]]

Потому что это фактически эквивалентно этому:

[[ ( ! 2 -eq 2 ) && ( 3 -eq 4 ) ]]

При этом, из-за укороченного вычисления, правая часть &&никогда не вычисляется и фактически эквивалентна этому гораздо более короткому выражению:

[[ ! 2 -eq 2 ]]

Что всегда будет ложным (1).

Короче говоря: внутри [[! влияетчастивыражения.

Предпочтительный

Использование !inside [[встречается гораздо чаще (и переносимо на большее количество оболочек (с помощью [)), но иногда может сбивать с толку, если явно не контролировать его с помощью разумного использования ()для ограничения степени отрицания (что может стать проблемой внутри [конструкций).

Но (в bash, ksh и zsh) результат ! [[довольно четко определен и его легче понять: выполнить все [[и отменить результат.

Какой из них следует использовать — вопрос личных предпочтений (и понимания).

Связанный контент