Есть ли какая-либо значимая/поведенческая разница между размещением ! внутри или снаружи тестов квадратных скобок?
например Есть ли разница между:
# if file exists but is empty, exit
[[ ! -s "${file}" ]] && exit 1
и
# if file exists but is empty, exit
! [[ -s "${file}" ]] && exit 1
Я спрашиваю в целом, а не конкретно по -s тесту. Например, меняется ли что-нибудь из этого при работе с числами или при выполнении нескольких тестов?
В первом случае ! является оператором, специфичным для команды [[ .... ]] и отрицающим следующее выражение. Во втором случае ! — это «оператор» (официального термина для него я не знаю), который инвертирует код завершения любой произвольной команды и используется здесь, в частности, для инвертирования кода завершения всей команды [[ ... ]].





Он сводит на нет все, что находится внутри скобок, если вы поместите его за скобки. Это «если нет» (отрицает соседний термин), только если вы поместите его в скобки. Рассмотрим несколько терминов с && (и ||), например
! [[ -s "/usr/bin/env" || "1" == "0" ]] && echo true
логически отличается от
[[ -s "/usr/bin/env" || ! "1" == "0" ]] && echo true
Разница в том, что у вас внутри более одного элемента.
! [[ A || B ]]эквивалентно[[ ! A && ! B ]](булева алгебра).