Альтернатива конструкции-l oop - PullRequest
25 голосов
/ 04 августа 2020

Общий комментарий: любой новый ответ, который дает новое и полезное понимание этого вопроса, будет вознагражден бонусом.

В справочном руководстве 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] Я не нашел более ранних версий, я считаю, что они предшествуют этому

1 Ответ

14 голосов
/ 05 августа 2020

[W] Почему это не распространяется на другие l oop -конструкции?

Связанные формы , а и до команды будут синтаксически неоднозначными, потому что вы не можете отделить тестовые команды от последовательных команд без четкого разделителя между ними, поскольку они оба определены POSIX быть составным перечисляет .

Например, оболочка, поддерживающая такие конструкции, может выбрать одну из групп скобок в приведенной ниже команде как последовательный -commands , и в любом случае это будет разумный выбор.

while true; { false; }; { break; }

Из-за своей неоднозначной формы эту команду можно преобразовать в любую из следующих команд; ни один из них не является более точным переводом, чем другой, и они делают совершенно разные вещи.

while true; do
    false
done
break
while true; { false; }; do
    break
done

Команда for невосприимчива к этой двусмысленности, потому что ее первая часть - переменная имя, за которым может следовать в и список слов, или особая форма составной команды (( - можно легко отличить от фигурной скобки, которая составляет ее вторую часть.

Дано что у нас уже есть согласованный синтаксис для команд , а и до , я действительно не вижу никакого смысла в распространении этой альтернативной формы на них.

...