POSIXシェル注釈と行の連続

POSIXシェル注釈と行の連続

私の質問を明確にするために編集してください。

POSIXは次のように言います。

<newline>が<backslash>の後にある場合(引用符を除く)、シェルはそれを行の連続として解釈します。入力をトークンに分割する前に、<backslash>と<newline>を削除する必要があります。

しかし、dash他の実装では、入力に最初にラベルが付けられます。\<newline>その結果、認識されず# this is a comment \廃棄されます。この動作はPOSIXに準拠していますか? POSIXは再び言いますトークン化の前に連続した行を削除する必要があります。

次の手順は実際にPOSIXと互換性がありませんか?

  1. 完全な入力を読んでください。"echo hello ... \<newline> ... bye"
  2. 引用符のないコンテンツを検索して\<newline>削除します。"echo hello ... bye"
  3. トークン化:"echo"(discard ' ')"hello"(discard ' ')(discard "# ... bye")

Ubuntuでdash-0.5.10.2-6 sh(ダッシュ)を使用すると、次のようになります。

$ cat /var/tmp/test.sh
echo hello # this is a comment \
echo bye

$ sh /var/tmp/test.sh
hello
bye

#以降のすべての内容はコメントとして処理され、\以前のすべての内容は削除されるため、\ <newline>の行の連続は効果がないためです。

しかし、POSIX「エスケープ文字(バックスラッシュ)」セクション状態

入力をトークンに分割する前に、<backslash>と<newline>を削除する必要があります。

~から#コメントはトークン化で行われます。

echo hello # this is a comment \
echo bye

次のようにする必要があります。

echo hello # this is a comment echo bye

これはshがPOSIXと互換性がないことを意味しますか?それとも、この場合、コメントが行連続より優先される理由はありますか?

ベストアンサー1

セクション1で説明されているように、シェルへの入力は文字ごとにスキャンされ、トークンに分割されます。トークン認識

[...] シェルは、以下の最初の適用可能な規則を適用して、入力をトークンに分割します。次の文字で入力に。

引用符はトークン認識プロセスの一部として扱われますが、質問の例を考慮すると、シェルは#その前に引用符で囲まれた改行文字に会います。

シェルが入力行をスキャンしている間に引用符なしのコメント文字に達すると、行の残りの部分(最後のバックスラッシュを含む)がコメントとして削除されます。

現在の文字がある場合、#その文字とすべての後続の文字(次の文字を除く)は<newline>コメントとして削除されます。行の終わりは<newline>コメントの一部とは見なされません。


引用した標準セクションは、引用するセクションでは、バックスラッシュの前に改行文字が表示されます。

引用符なしのAは、<backslash>a以外の後続の文字のリテラル値を保持する必要があります<newline>。が<newline>後に来ると、<backslash>シェルはそれを行の連続として解釈します。入力をトークンに<backslash>分割する前に削除する必要があります。<newline>[...]

これは、スキャナが実際に引用符なしのバックスラッシュを検出するまでは適用されません(トークン認識プロセスによって処理されます)。

現在の文字が<backslash>一重引用符または二重引用符であり、引用符が付けられていない場合は、引用符付きテキストが終了するまで後続の文字の引用符に影響します。引用規則は、「引用」で説明されているとおりです。

この回答ですでに述べたように、スキャナはコメント文字に最初に会い、バックスラッシュに会い、行の残りの部分(引用符を含む)をコメントとして扱うトークン認識ルールをトリガーします。したがって、行末改行への参照は決して適用されません。

おすすめ記事