で単純な数学演算を実行すると、#!/bin/sh
サブシェルが生成されますか?
例えば、
addition=$(( 1 + 1 ))
構文ではサブシェルの使用を提案しますが、これについては何も見つかりません。
答え1
$(cmd arg)
サブシェル環境で実行すると、そのcmd
出力(末尾の改行を除く)が拡張結果になります。
(cmd arg)
サブシェルで実行されますが、出力は影響を受けません。
したがって、 extra subshell と同じです$((cmd arg))
が、そうではありません。$(cmd arg)
$((...))
Kornシェルとは別の拡張です。 Korn シェルでは((arithmetic expression))
算術式が評価され(構文は C の構文によく似ています)、終了状態は式が 0 または 0 でないことを確認するかどうかを反映します。
これにより、次のような作業が可能になります。
if ((var < 10)); then
...
fi
これはそれを非常に似ているように見せますC
。
$
紹介のために拡大する。それを除いては$(cmd)
似ています。(cmd)
拡大する出力はそれを除いてはcmd
同じ$((arith))
です((arith))
拡大する算術式の評価結果です。
sh
ほとんどの場合、ksh88に基づくPOSIXは指定されていますが、$((...))
指定されていません((...))
。事実初期草案ではその$[...]
反対を意図したものだったので、見つけてbash
代替品としてzsh
支援することになったんです。$[...]
$((...))
IIRC、POSIXが最初にそれを指定することを考慮した主な理由$[...]
は、コマンド置換内のサブシェルとの競合が原因でした$((...))
。$((cmd arg))
$((echo x; echo y) | (tr xy ab))
ほとんどのシェルは次のように正しく識別されます。いいえ算術拡張は、$((cmd arg))
拡張の出力ではなく変数の算術値$((cmd))
に拡張されます。$cmd
cmd
POSIX 仕様の関連テキストは次のとおりです。
シェルコマンド言語の構文は、"$((" で始まる拡張に関してあいまいです。) これは、算術拡張またはサブシェルで始まるコマンド置換を導入できます。 算術拡張が優先されます。を決定する必要があります。算術拡張として解釈することができ、末尾が見つかった場合にのみ算術拡張として解釈できないと判断した場合、シェルは入れ子になった拡張を評価する必要はありません。エラーを報告します。適切なアプリケーションでは、「$(」と '(.them)を区別する必要があります。たとえば、単一のサブシェルに関連するコマンドの置き換えは、次のように書くことができます。
ksh
また、((...))
入れ子になったサブシェルと競合します。 POSIXはこれを指定しませんが、((...))
kshの動作を許可します。
実際、サブシェルおよび/またはcmdsubstを入れ子にするときは、角かっこの間にスペースを含める必要があります。
echo "$( (...) )"
( (a; b) | (c;d) )
答え2
これはデモですいいえサブシェルで実行:算術式で変数を変更できます。
$ x=5; echo "$(( x *= 2 ))"; echo "$x"
10
10
サブシェルの場合、echo $x
これが出力されます5
。
シェル算術を使用する場合、すべてのシェルが増分をサポートしているわけではありません(dash
現在のバージョンのDebianとその派生バージョンのデフォルト)は、変数を増やすのではなく解釈されます。/bin/sh
$(( ++i ))
$(( +(+i) ))
i