echo $a$((a=2))$a のパラメータ拡張と算術拡張の間のダイナミクス

echo $a$((a=2))$a のパラメータ拡張と算術拡張の間のダイナミクス

シェルは次のとおりです。GNU bash、バージョン5.1.16(1)-リリース(x86_64-pc-linux-gnu)

次のコマンドラインを検討しています。

a=1; echo $a$((a=2))$a

出力は次のとおりです

122

拡張は次の順序で処理されると推測されます。

  1. 変数にはa値が割り当てられます1
  2. 最初は$aパラメータ拡張に拡張されます。a=1
  3. $((a=2)) 次に算術拡張を実行してa に設定します2
  4. 次に、2番目の項目は算術拡張で設定された新しい値に$a展開されます。a2

私の理解が正しい場合、処理順序はシェルが算術拡張を行った後にパラメータ拡張に戻ることを意味します。

これは、bash拡張に明確な順序があるというGNU bashマニュアルの私の理解と矛盾しています。算術拡張は引数拡張後に実行されます。

ここで何が起こっているのかを説明できる人はいますか?

ベストアンサー1

これは、bash拡張に明確な順序があるというGNU bashマニュアルの私の理解と矛盾しています。算術拡張は引数拡張後に実行されます。

しかし実際にはそうではありませんman bash。注意深くお読みください:

拡張順序は、中かっこ拡張、パラメータと変数拡張、算術拡張、コマンドの置換(左から右へ)です。

コンマとセミコロンの使用に注意してください。チルダ、引数、変数、および算術拡張、コマンド置換はすべて、観察された動作に応じて左から右に同じレベルで発生します。


今後、POSIXテキストの対応する部分にはより明確な形式があります。。それは言う:

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

  1. チルダ拡張、パラメータ拡張、コマンド置換、および算術拡張は、最初から最後まで実行する必要があります。トークン認識のトピック5を参照してください。

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

  3. set -fが適用されない限り、パス名拡張を実行する必要があります。

  4. 見積もりの​​削除は常に最後に行う必要があります。

おすすめ記事