Общий комментарий: любой новый ответ, который дает новое и полезное понимание этого вопроса, будет вознагражден бонусом.
В справочном руководстве Bash упоминается, что Bash поддерживает следующие конструкции for-l oop:
for name [ [in [words ...] ] ; ] do commands; done
for (( expr1 ; expr2 ; expr3 )) ; do commands ; done
Удивительно, но следующий for-l oop также допустимы конструкции:
for i in 1 2 3; { echo $i; }
for ((i=1;i<=3;++i)); { echo $i; }
Эти необычные конструкции вообще не задокументированы. Ни в Bash manual , ни в Bash man-страницах , ни в The Linux Documentation Project эти конструкции не упоминаются.
При исследовании грамматики языка можно увидеть, что использование открывающих и закрывающих фигурных скобок ({ commands; }
) в качестве альтернативы do commands; done
является допустимой конструкцией, которая реализована как для циклов for, так и для select Bash -1.14.7 [1] .
Два других l oop -конструкции:
until test-commands; do consequent-commands; done
while test-commands; do consequent-commands; done
не имеют альтернативной формы.
Так как многие языки оболочки связаны между собой, можно обнаружить, что эти конструкции также определены там и частично задокументированы. В K SH руководстве упоминается:
По историческим причинам открывающие и закрывающие фигурные скобки могут использоваться вместо do
и done
, например,
for i; { echo $i; }
в то время как ZSH реализует и документирует аналогичные альтернативы для других l oop -конструкций, но с ограничениями. В нем указано:
Для команд if
, while
и until
в обоих этих случаях тестовая часть l oop также должна быть соответствующим образом ограничена, например [[ ... ]]
или (( ... ))
, иначе конец теста не будет распознан.
Вопрос: Каково происхождение этой конструкции и почему она не распространяется на другие l oop -конструкции?
Обновление 1: Есть несколько очень полезных и образовательных комментариев под этим сообщением, указывающих на то, что это недокументированная функция Bourne Shell, которая кажется результат C -vs- sh языковой битвы в первые дни.
Обновление 2: На вопрос: Почему эта языковая функция не задокументирована? в Gnu Bash список рассылки , я получил следующий ответ от Chet Ramey (нынешний ведущий разработчик GNU bash):
Это никогда не было задокументировано. Причина, по которой bash поддерживает его (недокументировано), заключается в том, что это была недокументированная функция оболочки Борна, которую мы реализовали для совместимости. В то время, 30 с лишним лет после go, существовали сценарии, в которых он использовался. Я надеюсь, что эти скрипты ушли на свалку истории, но кто знает, сколько людей сейчас используют эту конструкцию.
Я собираюсь оставить это недокументированным; люди в любом случае не должны его использовать.
Связанные вопросы / ответы:
Сноски: [1] Я не нашел более ранних версий, я считаю, что они предшествуют этому