Почему исключение a ] из тестовой команды [не останавливает выполнение скрипта?

#linux #bash

#linux #bash

Вопрос:

У меня есть сценарий Bash следующим образом.

 #!/bin/bash
if [ "1" -eq "1"
then echo "something"
else echo "some other thing"
fi
  

Когда я выполняю скрипт, я получаю следующий вывод

 test.sh: line 2: [: missing `]'
some other thing
  

что для меня непонятно, поскольку я исключил скрипт для завершения с ошибкой. Можно ли это объяснить более подробно, если это ожидаемое поведение?

Однако, когда я использую составную команду [[

 #!/bin/bash
if [[ "1" == "1"
then echo "something"
else echo "some other thing"
fi
  

я получаю ошибку, и скрипт прекращает выполнение дальше.

 test.sh: line 2: syntax error in conditional expression
test.sh: line 3: syntax error near `then'
test.sh: line 3: `then echo "something"'
  

Ответ №1:

[ это не синтаксис bash, это просто команда (команда со встроенной в оболочку реализацией, доступной для оптимизации производительности, да, но при условии того же поведения во время синтаксического анализа, что и стандартная /bin/[ внешняя реализация или любая другая команда). Помещение недопустимой ping команды или недопустимой grep команды в одну и ту же позицию также не делает синтаксис вашего скрипта недопустимым.

В отличие от этого, [[ это фактический синтаксис, который делает возможными функции, которыми он обладает [ (набор, который включает в себя распознавание шаблонов без их расширения в виде глобусов, подавление разделения строк и расширения глобуса, разрешение использовать amp;amp; и || для объединения тестов и т.д.), А также делает недопустимым использование, способное вызвать ошибку синтаксического анализа.


Если вы хотите уменьшить путаницу для читателей, рассмотрите возможность использования имени test вместо [ . Хотя [ и test обычно являются псевдонимами одной и той же команды (с единственной разницей в поведении, заключающейся в том, ] требуется ли это), читателям гораздо более наглядно понятно, что if test 1 -eq 1; then выполняется команда с именем test , а не какой-то специальный синтаксис оболочки.

Комментарии:

1. @thatotherguy Спасибо за редактирование. Я немного не решаюсь использовать < и > в [[ ]] , не уточняя, что они предназначены только для лексикографических, а не числовых сравнений, поэтому я выбрал другой набор примеров.

2. Еще лучше ^__^

Ответ №2:

 $ type [[ [
[[ is a shell keyword
[ is a shell builtin
  

[ является обычной встроенной. [[ это ключевое слово оболочки, и оно имеет особое синтаксическое значение (например, переменные не подвергаются разделению на слова). Таким образом, недопустимое использование [[ может быть ошибкой синтаксического анализа, мешающей правильному анализу скрипта, тогда как аналогичное использование [ — это просто встроенный возврат ненулевого кода выхода с возможным выводом некоторой ошибки. Для оболочки это имеет не больше значения, чем, скажем, false возврат ненулевого кода выхода.