Я не использовал эту конкретную конструкцию для bash встроенных test
/ [
команд, но я столкнулся с ней сегодня и запутался. Это выглядит так:
[ -n "${FOO}" -a -r ${FOO}/bar ] && echo OK
Я знаю, что каждый переключатель делает индивидуально, но я не уверен в поведении, когда они сгруппированы таким образом. В частности, часть -a -r [operand]
. Вот что должна сказать страница man
:
проверяет и [оценивает условные выражения, используя набор правил, основанный на количестве аргументов.
0 аргументов
Выражение ложно.
1 аргумент
Выражение истинно тогда и только тогда, когда аргумент не равен нулю.
2 аргумента
Если первый аргумент равен!, Выражение будет истинным тогда и только тогда, когда второй аргумент будет нулевым. Если первый аргумент является одним из унарных условных операторов, перечисленных выше в разделе УСЛОВНЫЕ ВЫРАЖЕНИЯ, выражение будет истинным, если унарный тест является истинным. Если первый аргумент не является допустимым унарным условным оператором, выражение является ложным.
3 аргумента
В указанном порядке применяются следующие условия. Если второй аргумент является одним из двоичных условных операторов, перечисленных выше в разделе Условные выражения, то результатом выражения является результат двоичного теста, использующего первый и третий аргументы в качестве операндов. Операторы -a и -o считаются бинарными, когда есть три аргумента. Если первый аргумент -!, Значение является отрицанием теста с двумя аргументами, использующего второй и третий аргументы. Если первый аргумент точно (а третий аргумент точно), результатом является проверка одного аргумента второго аргумента. В противном случае выражение является ложным.
4 аргумента
Если первый аргумент равен!, Результатом является отрицание выражения с тремя аргументами, состоящего из оставшихся аргументов. В противном случае выражение анализируется и оценивается в соответствии с приоритетом, используя правила, перечисленные выше.
5 или более аргументов
Выражение анализируется и оценивается в соответствии с приоритетом, используя правила, перечисленные выше. .
Хорошо, отлично. Так как я предоставляю 5 аргументов, выражение будет проанализировано и применены правила. Я предполагаю, что он будет разбит и оценен на 2 части, например:
[ -n "${FOO}" ] && [ -a -r ${FOO}/bar ] && echo OK
Но это не так, так как это дает [: -r: binary operator expected
, ему не нравится [ -a -r ... ]
. Конечно, это работает:
[ -n "${FOO}" ] && [ -a ${FOO}/bar ] && [ -r ${FOO}/bar ] && echo OK
И так же:
[ -n "${FOO}" -a ${FOO}/bar ] && echo OK
, но это не удается:
[ -n "${FOO}" -r ${FOO}/bar ] && echo OK
добавление к моей путанице - это та часть, которая говорит:
Операторы -a и -o считаются бинарными операторами, когда есть три аргумента
Как именно -a
обрабатывается как бинарный оператор? Я считаю, что он проверяет существование файла, но имеет ли он здесь другое поведение? Что это делает со вторым операндом? Как Bash встроенный test
анализирует аргументы в исходном примере? Чего мне не хватает?