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;}の予約語であるため、この場合は先頭に<space>
と<semicolon>
が必要です。クサラナンダの答えを受け入れる。クサラナンダの答えは私が必要とするものを扱っていますが、ほとんどは非公式で直感的な観点からです。{
予約語で(
あり、演算子であると指摘しています。Michael Homerもコメントで同じことを指摘しました-複合コマンドの定義は次のように述べています(強調を追加)これらの複合コマンドのそれぞれには、最初に予約語または制御演算子があります
{
シェル文法にリストされている、for
またはに類似した予約語として定義されているwhile
(質問の最後のコードブロックを参照)セクション2.9の状態(強調を追加):
特に、表現には、sが不要な場所(トークンの1つが演算子の場合)でのトークン間のスペースが含まれ
<blank>
ます。標準では
(
演算子として明示的に定義されていませんが、演算子(
と呼ばれます。具体的には、セクション2.9.2は言うパイプラインが予約語で始まる場合!また、command1がサブシェルコマンドである場合、アプリケーションは、command1の先頭の(演算子が!から1つ以上の文字で区切られていることを確認する必要があります。予約語!の直後に(演算子が続くことにより、
Digital Traumaによるスタックオーバーフローに関する質問は、予約語に関するセクション2.4を指摘しています。
この認識は、文字が引用されておらず、単語が次のように使用されている場合にのみ発生します。
-コマンドの最初の単語
Kusalanandaの回答で述べたように、「POSIX文法で示されるスペースは、シェル入力データに存在する必要があるスペースではなく、文法自体を表示する方法にすぎません。中括弧は予約語であり、 「で述べたように、彼らは空白に囲まれているマイケル・ホーマーコメントで: 『スペースは、それ自体で有意であったならば、彼らはにリストする必要があると思いプロダクション』
ケースは閉じられました。
{
と(
の両方の化合物コマンドのPOSIX定義によって予約語であると考えられる」参照 「これらの複合コマンドのそれぞれには、最初に予約語または制御演算子があります。」
' '
)を含める必要があったことを意味すると信じています。代わりに、スペースは単語がどんなトークンであるかによって暗示されます。
command : simple_command | compound_command | compound_command redirect_list | function_definition ;
は、コマンドを作成できる場所を示すプロダクションであり、単純なコマンド、複合コマンド、またはリダイレクトを伴う複合コマンド、または関数定義のいずれかです。