let
の引数において ()
のエスケープは必要です。もっと言えば *
などの特殊文字も本当はエスケープが必要です。
let c=($b**3)/2
は原則でいえばシンタックスエラーになるべきですが、 let
の引数の解釈規則が普通とは若干異なるため、イコールの直後に開きカッコが来るときだけたまたまエラーにならないようです。バグか仕様か分かりませんが当てにしないほうがいいです。
*
のエスケープが必要な点について補足します。 let a=3*3
と書いたとき、 a=3*3
はまず「a=3
で始まり、任意の文字が0個以上続き、 3
で終わる」ファイル名にマッチする glob パターンとして扱われ、ファイルが検索されます。ファイルが見つかればファイル名に展開され、見つからなかったときは文字通りの a=3*3
になります。よってパターンにマッチするファイルの有無で挙動が変わってしまいます:
$ let a=3*3
$ echo $a
9
$ touch 'a=333' # この名前のファイルを作る
$ let a=3*3 # パターン a=3*3 がファイル名 a=333 にマッチし、それに展開され、 a=333 が式として評価される
$ echo $a
333
$ let a=3\*3 # エスケープすればパターンにならないのでマッチしない
$ echo $a
9
let
はエスケープが面倒なので、数式を扱うのであれば (( ))
の使用をお勧めします。 (( b = 4 * ( $a - 1 ) ))
のように、エスケープ不要かつ空白を混ぜて書くことができます。