POSIXシェル:単語の最後の文字の場合、「$」は特別な意味を失いますか?

POSIXシェル:単語の最後の文字の場合、「$」は特別な意味を失いますか?

私が走ると、Ashes、Sprints、Slamsで

$ echo ab$

それは戻ってくる

ab$

この動作はPOSIXで指定されていますか、それともPOSIX互換シェル間の一般的な規則ですか? POSIX Shell Command Language ページにこの動作に関する言及がありません。

答え1

$それ自体には特別な意味はありません(try)。 (または)、、echo $などの他の後続の文字と組み合わせて拡張子を形成する場合にのみ特別な意味があります。$var${var}$(util)$((1+2))

「特別な」意味$は、拡張がPOSIX標準で定義されていることです。トークン認識:

現在の文字が引用符なしの$orの場合、`シェルは引用符なしの導入文字シーケンスor、または、および$${パラメータ$(拡張`、コマンド置換、または算術拡張の候補の開始を識別する必要があります$((。シェルは、拡張するデバイスの端を決定するのに十分な入力を読み取る必要があります(引用した章で説明したように)。文字を処理するときに入れ子になった拡張または引用符のインスタンスが置換で見つかった場合、シェルは見つかった構成に指定されているとおりに繰り返し処理する必要があります。置換の開始から終了までに見つかった文字(組み込み構造を識別するために必要な再帰を許可する)は、埋め込まれた、または含まれる代替演算子または引用符を含む、変更されていない結果マークアップに含める必要があります。トークンは置換が終了するまで区切ってはいけません。

したがって、$拡張が形成されない場合、他の解析規則が適用される。

前の文字が単語の一部である場合は、現在の文字をその単語に追加する必要があります。

それはあなたのab$ひもを覆います。

別の場合$(「新しい単語」$自体は次のようになります):

現在の文字が新しい単語の先頭として使用されます。

これ重要性$非標準拡張を含む生成された単語は、POSIXでは明示的に指定されていないと定義されています。

また、$の最後の文字はですが、$$これは現在のシェルのPIDを保持する変数でもあります。では、bash履歴!$拡張を呼び出すことができます(前のコマンドの最後の引数)。したがって、一般的にいいえ、$引用されていない単語の終わりは意味がありませんが、単語の終わりは少なくとも標準的な拡張を意味しません。

答え2

状況に応じて、これは明示的に指定されていないか(実装が必要に応じて実行される場合があります)、観察された方法で行われるべきです。特定のシナリオecho ab$ではPOSIXは、観察された「ab $」の出力を強制します。そしてこれは指定されていません。。最後に、さまざまなケースの簡単な要約です。

2つの要素があります。まず、単語としてラベルを付け、その単語を解釈することです。


トークン化

POSIXトークン化の要件Aは$有効な開始ではありません。パラメータ拡張コマンドの置き換えまたは算術置換WORD生成されるトークンの文字通りの一部として処理されます。これは規則5によるものです(「現在の文字が引用符なしの場合、または$シェル`は引用符なしの導入文字シーケンス内のパラメータ拡張、コマンド置換、または算術拡張の候補の開始を識別する必要があります。または$${それぞれ、$(または`$((」)ここでは、これらの拡張は不可能なので適用しないでください。パラメーター拡張には有効な名前が必要です。空の名前は無効です。

このルールは適用されないため、適用されるルールが見つかるまでこれを続けます。 2つの候補は、#8(「前の文字が単語の一部である場合は、現在の文字をその単語に追加する必要があります」)と#10(「現在の文字が新しい単語の先頭として使用されます」)です。それぞれecho a$に適用されますecho $

3番目の形式も特別なパラメータの名前ではないecho a$+bため、同じ状況に属します。+ルールの他の部分をトリガーするので、後でもう一度説明します。

したがって、仕様では文法的に$単語の一部として処理され、後でさらに処理されるように要求します。


単語拡張

このように入力を解析し、$それを単語として含めた後、単語拡張読んだすべての単語に適用されます。すべての単語が処理されます。個別に

明確に定義:

引用符のない「$」の後に次のいずれかの文字以外の文字が続く場合:

  • 数字
  • 特殊パラメータの1つの名前(参照:特殊パラメータ)
  • 変数名の最初の有効な文字
  • <left-curly-bracket>('{')
  • <left-parenthesis>

結果が指定されていません。

ここで、「未指定」は特別な用語である。

  1. この場合、一貫したシェルはすべての動作を選択できます。
  2. 適格アプリケーション特定の行動に依存できない

あなたの例echo ab$では$ 遅れないどの特徴そのため、ルールは適用されず、指定されていない結果は呼び出されません。まったく拡張が発生していない$ため、存在して印刷されます。

どこ会議上記の3番目のケースに適用されるものは次のとおりですecho a$+b。後に、数字では$ない、特殊パラメータ+@、、、、、、、または)、変数の始まり*#?-$!0名前(下線または文字ポータブル文字セット)または大括弧のいずれかです。この場合、動作は指定されません。一貫したシェル+拡張という特別なパラメータを考案することが許可されました。および適格申請書シェルがそうでないと仮定してはいけません。。シェルは、エラー報告など、必要な操作をすべて実行できます。

たとえば、POSIXモードを含むzshは「変数のセット」$+bと解釈されます。bそしてその場を 1 か 0 に変えます。また、~との拡張もあります=。これは規制に準拠した動作です。

このようなことが起こることができるもう一つの場所はですecho "a$ b"。繰り返しますが、シェルは必要なことを行うことができ、スクリプト作成者として$リテラル出力をしたい場合はエスケープする必要があります。それ以外の場合は効果があるかもしれませんが、依存することはできません。これは仕様の絶対的な文字ですが、これらの粒度は意図的または考慮されていないと思います。


要するに

  • echo ab$:テキスト出力、完全に指定
  • echo a$ b:テキスト出力、完全に指定
  • echo a$ b$:テキスト出力、完全に指定
  • echo a$b:パラメータ拡張b、完全に指定
  • echo a$-b:特殊パラメータ拡張-、完全に指定
  • echo a$+b: 指定されていない動作
  • echo "a$ b": 指定されていない動作

$単語の末尾のaに対する対応する動作は信頼でき、文字通り処理し、引数のecho一部としてコマンドに渡す必要があります。これはシェルの一貫性要件です。

関連情報