Bash:算術拡張、パラメータ拡張、およびカンマ演算子

Bash:算術拡張、パラメータ拡張、およびカンマ演算子

bash、カンマ式、および算術式内のパラメータ拡張について質問があります。私は同等でなければならないと思う2つのステートメントを持っていますが、そうではありません。

バッシュが機能する理由

n=3; k=10; echo $((n++,k=$n))

3?代わりに出力します4。 (予想通りに設定されていたnのに設定されていました。)4k3

代わりに、bashライン

 n=3; k=10; echo $((n++,k=n))

出力は4期待どおりです。 (nに設定されており4、にもk設定されています4。)

私は2つのbash行でn++with ++n、with、およびn=n+1withを置き換えようとしましたが、n=$((n+1))すべて同じ違いを示しました:すべてのスクリプトで、すべてのスクリプトでk=$n3k=n4


私の理解は、値が整数n(整数)の場合は算術式で同じ値を持つ必要があることです$nn(構造上(( ... ))これは算術式です。)bashマニュアルによると、算術評価セクションの算術式で:

   Shell variables are allowed as  operands;  parameter  expansion  is  performed  before  the
   expression  is  evaluated.  Within an expression, shell variables may also be referenced by
   name without using the parameter expansion syntax.

それでは、なぜbashは$nこの例とは異なる方法でそれを処理し、正確にどのようnに評価されますか$n


カンマ演算子を使用しないと、問題を再現できません。私が知る限り、コンマ演算子は各コンポーネントを評価するとき、そのコンポーネントのすべての副作用を含む各コンポーネントのサブ式を左から右に評価します。コンマ式の値は、最後に評価されたコンポーネント(最も右側)の値です。


この質問はもう少し複雑なスクリプトの文脈から来ており、最終的に問題を示すためにこの簡単な例に絞り込みました。

それでは、算術拡張、パラメータ拡張、またはコンマ演算子について私が何を誤解していますか?

すでに回避策があるため、回避策を探しているわけではありません。 withバージョンは期待nどおりに機能します。私はbashが含まれているバージョンで何をしているのか、なぜそれが含まれているバージョンとは異なる機能を実行するのかを$n知りたいと思います。$nn

答え1

シェルパラメータ拡張が発生します。式を評価する前にコンマ処理を含める:

式は二重引用符で囲まれたように処理されますが、括弧内の二重引用符は特に処理されません。式のすべてのトークンは、パラメータと変数の拡張、コマンドの置き換え、および引用符の削除を受けます。結果は評価する算術式として扱われます。

あなたはこれを見ることができます

unset n
echo $((n++,k=$n))

間違った情報、

bash: n++,k=: syntax error: operand expected (error token is "=")

$n全体の演算式が処理される前に、ディスプレイが交換されます。

あなたの場合、評価された式は次のとおりです。

n++,k=3

答え2

内部的には、$((...))二重引用符と同様に、拡張が最初に実行され、次に結果が評価されます。

したがってn=3; k=10; echo $((n++,k=$n))(またはn=1; echo "$((++n + $n))"限定されない,)で評価された算術式はですn++, k=3

これには次のものが必要です。

n=3; k=10; echo "$((n++,k=n))"

(算術拡張はPOSIXシェルの他の形式の単語拡張と同様に分割+グローブの影響を受けるため、引用符も参照してください。)


$((hash[$key]++))1では、一部のシェルが含まれている場合は正しく処理しようとするため、配列と連想配列の呼び出しでいくつかの変更を見つけることができます。$key]

関連情報