expr 算術括弧: 3 * (2 + 1)

expr 算術括弧: 3 * (2 + 1)

expr括弧を嫌うようです(数学で明示的な演算子の優先順位に使用されます)。

expr 3 * (2 + 1)
bash: syntax error near unexpected token `('

Bashで演算子の優先順位を表現する方法は?

答え1

代わりに算術拡張を使用できます。

echo "$(( 3 * ( 2 + 1 ) ))"
9

私の個人的な意見では、を使用するよりもこれが良いようですexpr

~からman bash

算術拡張 算術拡張を使用すると、算術式を評価して結果を変更できます。算術拡張の形式は次のとおりです。

         $((expression))

式は二重引用符で囲まれたように処理されますが、括弧内の二重引用符は特に処理されません。式のすべてのトークンは、パラメータ拡張、文字列拡張、コマンド置換、および引用符の削除を受けます。算術拡張は入れ子にすることができます。

評価は、以下の算術評価項目に記載されている規則に従って行われます。式が無効な場合、bash は失敗を示すメッセージを出力し、置換は発生しません。

答え2

Bash 組み込みコマンドを使用するlet別の方法:

$ let a="3 * (2 + 1)"
$ printf '%s\n' "$a"
9

ノート

〜のように@Stéphane Chazelasが指摘しました。、読みやすくするため、または算術演算にbash使用する必要があります。((...))exprlet

簡単に移植するには、$((...))次のものを使用してください。@Bernhardが返信しました

答え3

expr現代のシェルでは算術を使用する理由はありません。

POSIX は$((...))スプレッド演算子を定義します。したがって、すべてのPOSIX互換シェル(shすべての最新のUnixファミリーシェル、ダッシュ、バッシュ、ヤッシュ、mksh、zsh、ポッシュ、ksh...)で使用できます。

a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))

kshlet同じ型の算術式を渡して他のものに拡張することはありませんが、次のように式がゼロであるかどうかによって終了状態を返す組み込み関数も導入されましたexpr

if let 'a = 3 * (2 + 1)'; then
  echo "$a is non-zero"
fi

exprしかし、引用するとぎこちなく読みにくくなります(もちろんそうではありませんが)、他の形式もksh導入されます。((...))

if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then
  echo "$a is non-zero and 3 > 1"
fi
((a+=2))

より明確で使用する必要があります。

letと、((...))とにのみ適用されます。他のシェルへの移植性が必要な場合は、この構文を優先する必要があります。 POSIX以前のBourne様シェル(通常はBourneシェルまたはAlmquistシェルの以前のバージョン)でのみ必要です。kshzshbash$((...))expr

Bourne以外の側面には算術演算子が組み込まれたシェルがあります。

  • csh/ tcsh(実際に算術評価機能が組み込まれた最初のUnixシェル):

    @ a = 3 * (2 + 1)
    
  • akanga(基準rc

    a = $:'3 * (2 + 1)'
    
  • 歴史的な記録のために、1989年にUsenetにリリースされたAlmquistシェルの元のバージョンには組み込みexpr機能がありましたが(実際にはこの機能とマージされていますtest)、後で削除されました。

答え4

括弧と引用符を使用してください。

expr 3 '*' '(' 2 '+' 1 ')'
9

引用符は、 bash が括弧を bash 構文として解釈するのを防ぎます。

関連情報