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
/* '{' '}' '!' */
Отже, що могло б бути точним мотивом цієї розбіжності?
Примітки відповідей:
Переміщена прийнята галочка на відповідь Ісаака, оскільки вона забезпечує q уоте форму самого стандарту , який безпосередньо стосується мого питання:
Наприклад, '(' і ')' є операторами управління, так що
<space>
в списку не потрібно. Однак '{' і '}' є зарезервованими словами у {list;}, так що в цьому випадку провідні<space>
і<semicolon>
обов'язкові.Приймаючи відповідь Кусалананди. Відповідь Кусалананди стосується того, що мені потрібно, хоча переважно з неформальної та інтуїтивної точки зору; він вказує, що{
це зарезервоване слово і(
є оператором. Майкл Гомер також зазначив те саме в коментарях - що визначення Зведеного командування говорить (наголос додано):Кожна з цих складових команд має зарезервоване слово або оператор управління на початку
{
визначаються як зарезервоване слово, схоже наfor
абоwhile
, перелічене в Граматиці Shell (див. останній блок коду у питанні)Розділ 2.9 констатує (додано наголос):
Зокрема, подання включає проміжки між лексемами в тих місцях, де
<blank>
s не буде необхідним (коли один з лексем є оператором).Хоча стандарт явно не визначає
(
як оператор,(
його називають оператором; зокрема, йдеться в розділі 2.9.2Якщо конвеєр починається із зарезервованого слова! а command1 - це команда додаткової оболонки, програма повинна забезпечити (оператор на початку команди1 відокремлений від!! одним або декількома символами. Поведінка зарезервованого слова!
Питання про переповнення стека цифровою травмою вказує на розділ 2.4 "Зарезервовані слова":
Це розпізнавання відбувається лише тоді, коли жоден із символів не цитується і коли слово використовується як:
-Перше слово команди
Як згадується у відповіді Кусалаланда "Пробіли, показані в граматиці POSIX, - це не пробіли, які повинні бути там, у вхідних даних оболонки, а лише спосіб відображення самої граматики. Саме той факт, що дужки є зарезервованими словами, означає, що вони повинні бути оточені пробілом ". Як згадував Майкл Гомер у коментарях:" Якби простори самі по собі були значущими, їх потрібно було б перерахувати у виробництві "
Справа закрита.
{
і (
обидва вважаються зарезервованими словами за визначенням POSIX складної команди", пор. Msgstr "Кожна з цих складених команд на початку має зарезервоване слово або оператор управління ".
' '
). Натомість пробіли мають на увазі те, якими лексемами є слова.
command : simple_command | compound_command | compound_command redirect_list | function_definition ;
, це виробництво, яке говорить про те, де ви можете мати команду, це може бути проста команда, складна команда або складна команда з перенаправленням, або визначення функції.