拡張間の順序を理解する方法は?

拡張間の順序を理解する方法は?

POSIX 7から始める:

単語拡張の順序は次のとおりです。

  1. チルダ拡張(セクション2.6.1を参照)、パラメータ拡張(セクション2.6.2を参照)、コマンドの置き換え(セクション2.6.3を参照)、および算術拡張(セクション2.6.4を参照)は、最初から最後まで実行する必要があります。セクション2.3の項目5を参照してください。

  2. IFSが空でない場合は、手順1で作成したフィールド部分に対してフィールド分割を実行する必要があります(セクション2.6.5を参照)。

  3. set -fが適用されない限り、パス名拡張を実行する必要があります(セクション2.6.6を参照)。

  4. 見積もりの​​削除(セクション2.6.7を参照)は常に最後に実行する必要があります。

  1. チルダ拡張、パラメータ拡張、コマンド置換、算術拡張は指定された順序で実行されますか?

    それらの間の順序は重要ですか?それでは、なぜ順序がそのままなのか、どうすればわかりますか?

  2. フィールド分割後にパス名拡張が発生し、フィールド分割前に別の拡張が発生するのはなぜですか?

    特に、チルダ拡張とパス名拡張の両方がパス名とファイル名に関連しています。

  3. POSIXに中かっこ拡張がありませんか?

  4. 「単語拡張」に注目しました。拡張機能は、トークン識別子がWORDのトークンにのみ適用され、他のトークン識別子(NAME、特定の演算子、NEWLINE、IO_NUMBER、ASSIGNMENTなど)を持つトークンには適用されませんか?

答え1

チルダ拡張、パラメータ拡張、コマンド置換、および算術拡張が同じ手順に一覧表示されます。処刑されたという意味だ。同時に。チルダ拡張の結果はパラメータ拡張を経ず、パラメータ拡張の結果はチルダ拡張を経ません。たとえば、値がある場合、foo単語$(bar) quxはステップ1で展開されます$foo$(bar) quxパラメータ拡張によって生成されたテキストは、ステップ1でそれ以上の変換を行わずにステップ2で分割されます。

「開始から終了まで」とは、左から右に処理することを意味します。たとえば、割り当てが発生した場合に重要です。a=1; echo $a$((a=2))$a印刷。算術拡張は、最初の引数拡張と2番目の引数拡張(1222に設定)の間で行われるためです。$((a=2))a$a$a

この順序の理由は、過去の使用法によるものです。 POSIXは通常、既存の実装に従い、新しい動作をほとんど指定しません。ほとんどの場合、POSIXは複数のシェルに従います。コーエンシェルただし、存在しないほとんどの機能は省略します。ボンシェル(Bourneシェルはほとんど使用されていないため、POSIXの次のバージョンには新しいksh機能が含まれる可能性があります。)

Bourneシェルがパラメータ拡張、フィールド分割、およびワイルドカードを実行する理由は、ワイルドカードを変数に格納できるためです。一致を表すファイル名のリストをa設定*.txt *.pdfしてから使用でき、名前リストの一致が続きます(2つのパターンが一致すると仮定)。 )。 (これが最高のデザインであると言うわけではありません。単にそのように設計されているだけです。)人々がKornシェルの特定の段階にコマンド置換を配置したい理由がわかりません。パラメータ拡張に近いので、一緒に実行するのは妥当です。$a*.txt*.pdf$(…)${…}

チルダ拡張の位置は歴史的に奇妙です。~$some_user名前がvalue変数のユーザーのホームディレクトリに書き込んで拡張できるように、後で配置する方が合理的ですsome_user。なぜできないのかわかりません。このコマンドには、チルダ拡張の結果が他の拡張の影響を受けないという特別なステートメントも必要です(引用符によると、HOME2つの単語に拡張され、フィールド分割によって拡張されますが、シェルはこれを実行しません/foo bar)、POSIX .2008では、「チルダ拡張で生成されたパス名は引用符で処理する必要があります」と明示的に述べています。~/foobar

POSIXには中かっこ拡張はありません。それ以外の場合は、仕様でこれを指定します。

ワード拡張はWORDでのみ行われます。次のセクションで説明されている注意事項があります(フィールド分割とパス名の作成は、複数の単語が許可されているコンテキストでのみ行われます(二重引用符の間には行われません)。NAME、NEWLINE、IO_NUMBERなどには拡張できます。ある項目は含まれていません。

答え2

(1)に関して、このシーケンスは既存の実装に基づいています。文章を書く人が、他の殻のための異なる呪文が考慮されることを知っていれば基準、彼らはこれを可能にするためにフレーズにいくつかの余裕を提供します。で述べたように2.6 単語拡張他の注文がこの基準を満たすことができるという兆候はありません。

繰り返しますが、(2)の場合、これは既存の実装に基づいていることに注意してください。いくつかの興味深い違い領域(例:BSD対SVr4)がありますが、元の実装の理由を標準で必ずしも見つけることはできません。理由このセクションでは、委員会が矛盾する選択肢の1つを選択した理由をまとめます。

(3)の場合、言及した「中括弧の拡張」は、以下に関連する可能性があります。2.6.2 パラメータ拡張(POSIXでは必ずしもそうではありませんが、他の可能性もあります)。

最後に(4)、覚える一つNAMEどんな種類なのかWORD。単語拡張が適用されます。名前

答え3

  1. 最初の4つの拡張注文:

トリガーは、チルダ拡張~、パラメータ拡張$nameと合計${name}、コマンド置換合計$()` `算術拡張など、各拡張ごとに異なります$((...)))。したがって、ある拡張を他の拡張と混同することはできず、各拡張は一度だけ実行されるため、順序は重要ではありません。パラメータ拡張を実行したトークンは、コマンド置換を実行しません(例:)。
混乱する可能性がある拡張のタイプの1つは算術拡張です。これは、パラメータ拡張、拡張、文字列拡張、コマンド置換、および引用符の削除がある可能性があるためです。さらに、算術拡張は入れ子にすることができます。しかし、これはすべて検出された算術拡張の内部で発生し、外部ではありません。

最も重要な順序は左から右です。

結局のところ、上記の拡張の結果(引用されていない場合)は、フィールド分割とパス名拡張(順番に)の影響を受けます。

すべての拡張は最終的に提案から削除されます。

  1. いいえ、POSIXには中かっこ拡張はありません。
  2. この場合、単語とマークは同じ概念を表すことがよくあります。

関連情報