TL; DR : Почему группе скобок POSIX нужны пробелы после {
зарезервированного слова, а в подоболочке нет после зарезервированного слова (
?
Грамматика оболочки POSIX определяет группу скобок и подоболочку следующим образом
brace_group : Lbrace compound_list Rbrace
subshell : '(' compound_list ')'
Теперь, если мы читаем это буквально, пробелы важны. Это будет означать, что должно быть пространство, обозначающее открывающую и закрывающую скобки и скобки, как в
{ echo hello world; }
( echo hello world )
Это также будет соответствовать определениям составных команд :
Каждая из этих составных команд имеет зарезервированное слово или оператор управления в начале и соответствующее зарезервированное слово или оператор терминатора в конце.
Однако то, что не имеет смысла, так это то, почему (list)
и ( list )
работают просто отлично (это место после (
не требуется), однако расширение скобки должно иметь начальное пространство, то есть {echo hello;}
не будет работать.
Конечно, зарезервированное слово, рассматриваемое как слово оболочки, будет иметь смысл, если впоследствии потребуется место для выравнивания с концепцией разбиения поля , однако само определение не упоминает пробелы. Кроме того, если {
и (
оба считаются зарезервированными словами , по определению POSIX соединения команды, поэтому они рассматриваются по- разному в отношении космического характера после этих зарезервированных слов? Теперь руководство ksh (1) заявляет:
Слова, являющиеся последовательностями символов, отделяются символами пробела без кавычек (пробел, табуляция и новая строка) или метасимволами (<,>, |,;, &, (и))
Другими словами, имеет смысл, что ksh будет распознавать (
как разделитель слов, где первое слово будет назначением команды или переменной. POSIX, однако, не упоминается (
как метасимвол. Единственное возможное объяснение, которое я нашел в отношении грамматики POSIX, - это то, что {
он считается «токеном», где (
он не указан как единое целое.
/* These are reserved words, not operator tokens, and are
recognized when reserved words are recognized. */
%token Lbrace Rbrace Bang
/* '{' '}' '!' */
Так, что было бы точным обоснованием этого несоответствия?
Принятый ответ Примечания:
В ответ на вопрос Исаака перенесена принятая галочка , поскольку он предоставляет саму форму стандарта , которая непосредственно касается моего вопроса:
Например, '(' и ')' являются управляющими операторами, поэтому нет
<space>
необходимости в (list). Однако '{' и '}' являются зарезервированными словами в {list;}, так что в этом случае ведущие<space>
и<semicolon>
обязательные.Принимая ответ Кусалананды. Ответ Кусалананды касается того, что мне было нужно, хотя в основном с неформальной и интуитивной точки зрения; оно указывает{
на зарезервированное слово и(
является оператором. Майкл Гомер также отметил в комментариях то же самое - это определение составной команды (выделение добавлено):Каждая из этих составных команд имеет зарезервированное слово или оператор управления в начале
{
определяются как зарезервированное слово, подобноеfor
илиwhile
, перечисленное в грамматике оболочки (см. последний блок кода в вопросе)Раздел 2.9 гласит (выделено):
В частности, представления включают в себя расстояние между токенами в некоторых местах, где
<blank>
s не требуется (когда один из токенов является оператором).Хотя стандарт явно не определяет
(
оператор,(
он называется оператором; в частности, в разделе 2.9.2 говоритсяЕсли конвейер начинается с зарезервированного слова! и command1 - команда subshell, приложение должно гарантировать, что оператор (в начале команды command1 отделяется от! одним или несколькими символами. Поведение зарезервированного слова!, за которым сразу следует оператор (, не определено.
Вопрос о переполнении стека цифровой травмой указывает на раздел 2.4 о зарезервированных словах:
Это распознавание должно происходить только тогда, когда ни один из символов не указан в кавычках и когда слово используется как:
-Первое слово команды
Как упоминалось в ответе Кусалананды: «Пробелы, показанные в грамматике POSIX, - это не пробелы, которые должны присутствовать во входных данных оболочки, а просто способ отображения самой грамматики. Это тот факт, что фигурные скобки являются зарезервированными словами, что подразумевает, что они должны быть окружены пробелами "Как упоминал Майкл Гомер в комментариях:" Если бы места были сами по себе значительными, их нужно было бы включить в производство "
Дело закрыто.
{
и(
оба считаются зарезервированными словами по определению составной команды POSIX», см. «Каждая из этих составных команд имеет зарезервированное слово или оператор управления в начале».' '
). Вместо этого пробелы подразумеваются тем, что токены являются словами.command : simple_command | compound_command | compound_command redirect_list | function_definition ;
, это постановка, в которой говорится, где вы можете иметь команду, это может быть простая команда, составная команда или составная команда с перенаправлением или определение функции.Ответы:
Это ограничение способа, которым оболочка разбивает строки на токены.
Оболочка считывает строки из входного файла и в соответствии с разделом 2 «Введение в оболочку» преобразует их в слово или оператор :
{это зарезервированное слово
Некоторые слова являются зарезервированными словами
Слова, которые должны распознаваться как слова, должны быть разделены .
В основном по пробелам (пункт 7) и по операторам.
(является оператором
Операторы стоят сами за себя :
Где «операторы» :
Операторы перенаправления :
Управляющие операторы :
Вывод
Таким образом, '(' и ')' являются управляющими операторами, а '{' '}' являются зарезервированными словами.
И точно такое же описание вашего вопроса находится внутри спецификации :
Что точно объясняет, почему после a требуется пробел (или какой-либо другой разделитель)
{
.Это действительно:
Как это:
Эта:
Или даже это:
источник
Разница между фигурными скобками и скобками в том , что фигурные скобки (и
!
) являются зарезервированными словами, так же , какfor
,if
, иthen
т.д. , а Скобки операторы управления. Слова должны быть разделены пробелами.Это означает, что так же, как вы не можете иметь
ты не можешь иметь
или
Пробелы, показанные в грамматике POSIX, - это не пробелы, которые должны присутствовать во входных данных оболочки, а просто способ отображения самой грамматики. Тот факт, что фигурные скобки являются зарезервированными словами , означает, что они должны быть окружены пробелами, а скобки подоболочки - нет.
источник
(
как оператор? По крайней мере, в разделе грамматики;
. Спасибо за это.()
управляющие операторы, подобные|
тем, что оба включают в себя подоболочки. И{ }
работает в текущей оболочке и не может включать в себя подоболочку.(