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

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

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などには拡張できます。ある項目は含まれていません。

おすすめ記事