Когда в операторе Bash if требуются квадратные скобки?

Обычно я использую квадратные скобки в операторе if:

if [ "$name" = 'Bob' ]; then ...

Но когда я проверяю, удалось ли grep, я не использую квадратные скобки:

if grep -q "$text" $file ; then ...

Когда в операторе if необходимы квадратные скобки?


person Misha Moroshko    schedule 19.01.2012    source источник
comment
Одинарные квадратные скобки совместимы с несколькими оболочками, однако некоторые из них, включая Bash, поддерживают предпочтительную двойную квадратную скобку. См. BashFAQ/031 для получения дополнительной информации. См. также help '['   -  person Dennis Williamson    schedule 20.01.2012


Ответы (3)


Квадратные скобки являются синонимом команды test. Оператор if проверяет статус выхода команды, чтобы решить, какую ветвь выбрать. grep -q "$text" — это команда, а "$name" = 'Bob' — нет, это просто выражение. test — это команда, которая принимает выражение и вычисляет его:

if test "$name" = 'Bob'; then ...

Поскольку квадратные скобки являются синонимом команды test, вы можете переписать ее как исходное выражение:

if [ "$name" = 'Bob' ]; then ...
person chepner    schedule 19.01.2012
comment
@chepner: Почему if $boolean_var ; then ... не требует скобок? - person Misha Moroshko; 20.01.2012
comment
@misha, если ваш $boolean_var имеет значение true или false, это работает, потому что вы выполняете команду true или false. - person glenn jackman; 20.01.2012
comment
if $boolean_var ; then ... не работает, если $boolean_var имеет значение 0 или 1, см. man true и man false. - person derFunk; 08.01.2014
comment
@derFunk: Это сработало бы, если бы у вас были команды 0 и 1 в вашем $PATH, но это было бы некрасиво. - person Keith Thompson; 16.08.2016
comment
проверка орфографии не любит скобки, но работает с тестовым оператором в VSCode. - person johnrubythecat; 22.07.2018
comment
Тогда у проверки орфографии есть проблема. [ — это стандартный псевдоним для test. - person chepner; 22.07.2018

[ на самом деле является командой, эквивалентной (почти, см. ниже) команде test. Это не часть синтаксиса оболочки. (И [, и test, в зависимости от оболочки, часто также являются встроенными командами, но это не влияет на их поведение, за исключением, возможно, производительности.)

Оператор if выполняет команду и выполняет часть then, если команда выполнена успешно, или часть else (если есть), если она терпит неудачу. (Команда завершается успешно, если она завершается со статусом ($?) 0, завершается ошибкой, если завершается с ненулевым статусом.)

In

if [ "$name" = 'Bob' ]; then ...

команда

[ "$name" = 'Bob' ]

(Вы можете выполнить эту же команду напрямую, без if.)

In

if grep -q "$text" $file ; then ...

команда

grep -q "$text" $file

man [ или man test для получения дополнительной информации.

СНОСКА. Команда [ почти эквивалентна команде test. Разница в том, что [ требует ] в качестве последнего аргумента, а test нет -- и фактически не позволяет этого (точнее, test не обрабатывает аргумент ] специально; например, это может быть допустимое имя файла) . (Это не должно было должно реализовываться таким образом, но [ без соответствующего ] заставило бы многих очень нервничать.)

person Keith Thompson    schedule 19.01.2012
comment
проверка орфографии не любит скобки, но работает с тестовым оператором в VSCode. - person johnrubythecat; 22.07.2018
comment
@johnrubythecat: О какой проверке орфографии вы говорите? Если это что-то, предназначенное для проверки орфографии английского текста, то, конечно, оно не будет в восторге от синтаксиса оболочки. - person Keith Thompson; 23.07.2018
comment
плюс один для аргумента nervous. - person Timo; 06.08.2020

Лучший способ думать о синтаксисе [ ... ] — это рассматривать [ как программу, которой она и является!

Проверь это:

~ $ ls /usr/bin/\[ 
/usr/bin/[

с другой стороны, вы, вероятно, не используете эту версию, поскольку bash также предоставляет [ как встроенную оболочку.

В любом случае, чтобы ответить на ваш вопрос: что делает if, так это запускает команду, которую вы ему даете, и видит, что возвращаемое значение равно 0 или нет. Вы используете [ для других, более интересных сравнений, таких как сравнение строк. См. man [ и man bash.

person cha0site    schedule 19.01.2012
comment
На странице руководства bash нет ничего, что указывало бы на то, что [ реализовано внутри, я думаю, для этого и предназначен [[. - person PhilHibbs; 17.09.2012
comment
@PhilHibbs: я почти уверен, что [ встроен. Вот почему builtin [ работает. [[ несколько отличается от [, он делает разные вещи. - person cha0site; 22.09.2012
comment
@PhilHibbs: Посмотрите раздел ВСТРОЕННЫЕ КОМАНДЫ ОБОЛОЧКИ на странице руководства bash. test expr и [ expr ] перечислены вместе. - person chepner; 09.10.2012
comment
@PhilHibbs: Также попробуйте type -a [ - person Keith Thompson; 22.04.2014