算術

算術 の Bash

{other: "%{count}個の演習"}

算術について

Bashは算術演算ができますが、整数でしかできません。 浮動小数点の計算が必要な場合は、外部プログラム(awkやbcなど)を呼び出す必要があります。

算術演算子は、マニュアルのShell Arithmeticに(優先順位の順で)記載されています。

さらに、Bashが算術演算を行うのは特定の場所だけです(これらは算術の「コンテキスト」と呼ばれます)。

算術展開

算術展開はコマンド置換に似ていますが、二重の括弧を使います。

$(( expression ))

この構文は、式を評価した結果に展開されます。 式の結果を変数に格納するためによく使われます。

x=$(( 3 + 4 ))
Note

括弧の中に入れる空白の量は自由です。 スタイルと読みやすさの問題です。

x=$(( 3 + 4 ))
y=$((5+6))

この記事の筆者は、括弧の中で算術式がより見やすくなるように、空白を入れるのが好みです。

算術条件式

算術条件式は、先頭の$を_付けずに_、二重の括弧の中で実行します。

(( expression ))

これは結果に展開されません。 しかし、_終了ステータス_を生成します。

  • 式の結果がゼロ以外であれば、終了ステータスは0(成功)です。
  • 式の結果がゼロであれば、終了ステータスは1(失敗)です。
Note

((の中では、BashはC言語と同じ真偽の考え方を使います。ゼロはfalse、ゼロ以外はtrueです。 これは、Bashが終了ステータスを評価する方法とは逆です!

この構文は、ふつう次の2つの場所で使います。

  1. if文やwhileループのCOMMAND部分として。

    if (( x == y - 1 )); then ...
    while (( y > 0 )); do ...
    
  2. 変数の値を変更するための単独のコマンドとして。

    (( x = x + 1 ))
    echo "new value for x is $x"
    
    Caution

    この方法の算術演算をset -eと組み合わせて使うときは注意してください。 式がゼロと評価されると、終了ステータスはゼロ以外になり、Bashは終了します。

    x=0
    (( x++ ))
    echo "you will see this"
    
    set -e
    x=0
    (( x++ ))
    echo "shell exits on the previous line; you won't see this"
    

    ++演算子についてのより詳しい議論は、Postincrement vs Preincrementの記事を参照してください。

算術コンテキストを使えるその他の場所

算術コンテキストになる場所は、ほかにもいくつかあります。

  • 算術forループ。

    for (( i = 0; i < 10; i++ )); do
        echo "$i"
    done
    
  • 数値インデックス付き配列のインデックス部分。

    echo "The next element is ${array[x + 1]}"
    # ................................^^^^^
    

    配列についてもっと知りたい場合は、配列のコンセプトドキュメントを読んでください。

  • ${var:offset:length}展開のオフセット部分と長さ部分。

  • letビルトインコマンド。

    • (( expression ))はlet "expresson"より好まれることに注意してください。 算術条件式の構文と違い、letの式はファイル名展開と単語分割の影響を受け、クォートが必要です。
  • 変数に「整数属性」がある場合の変数代入。

    # variable x does not have the integer attribute
    x="3 + 4"
    declare -p x      # => declare -- x="3 + 4"
    
    # variable y has the integer attribute
    declare -i y
    y="4 + 5"
    declare -p y      # => declare -i y="9"
    
    Note

    declare -iの用途は限られている、と筆者は考えています。 その主な利点は、「裸の」算術演算(算術式の構文を使わないもの)を可能にすることです。 これにより、コードを読む人が混乱する可能性があります。算術式が予期しない場所で評価されるからです。

算術式で変数を使う

算術コンテキストの、可読性を高める1つの側面を紹介します。

height=10
width=20
area=$(( height * width ))

算術式の中の変数から$が消えていることにお気づきになりましたか? Bashではそれができます。 式がずっと読みやすくなります。

マニュアルには次のように書かれています。

式の中では、シェル変数はパラメータ展開の構文を使わずに、名前で参照することもできます。

配列の要素でも同じことができます。

point1=(10 15)  # these are (x, y) coordinates
point2=(20 7)
distance_squared=$(( (point1[0] - point2[0])**2 + (point1[1] - point2[1])**2 ))

ただし、その他のパラメータ式は専用の構文を使う必要があります。 たとえば、文字列の長さを2倍にする場合です。

s="hello world"
len=$(( ${#s} * 2 ))

位置パラメータも同様です。 最初の2つの位置パラメータが幅と高さを表しているなら、次のようになります。

area=$(( $1 * $2 ))
GitHubで編集 リンクは新しいウィンドウまたはタブで開きます