)%E3%80%81(())%E3%82%92%E4%BD%BF%E3%81%86.png)
シェルスクリプトではexpr $a*$b
。$(($a+$b))
(($a+$b))
ただし、すべてのリソースで(())
整数の計算に使用されるため、使用しないことをお勧めします。
それでは、$(())
変数があるときに整数値の代わりに何を使うべきですか?$(())
変数が浮動小数点値を受け取ることができる場合は、代わりに何を使用する必要がありますか?
答え1
算術の場合、
expr
これは古代です。使用しないでください。 *$((...))
そして((...))
非常に似ています。両方とも整数計算のみを実行します。違いは、$((...))
計算結果を返し、((...))
計算結果を返さないことです。$((...))
文に非常に便利ですecho
。$ a=2; b=3; echo "$((a*b))" 6
((...))
変数を割り当てたり終了コードを設定したりする場合に便利です。$ a=3; b=3; ((a==b)) && echo yes yes
浮動小数点の計算が必要な場合、
bc
または以下を使用しますawk
。$ echo '4.7/3.14' | bc -l 1.49681528662420382165 $ awk 'BEGIN{print 4.7/3.14}' 1.49682
*BTW、expr
globは、globが不十分で正規表現にPOSIXメソッドが必要な場合に文字列を処理するのにまだ役立ちます。
答え2
exprは古いですが、使用は限られていると思います。文字列を検索するとしましょう。 grepをPOSIXに保つには、パイプを使用する必要があります。
if echo november | grep nov
then
: do something
fi
exprはパイプなしでこれを行うことができます。
if expr november : nov
then
: do something
fi
唯一の問題は、exprが固定文字列で動作することです。したがって、先頭の後に一致させるにはREGEXPを変更する必要があります。
if expr november : '.*ber'
then
: do something
fi
(( ))
この構造についてPOSIXではないだから避けるべきです。
に関しては、$(( ))
ドル記号を含める必要はありません。
$ fo=1
$ go=2
$ echo "$((fo + go))"
3
答え3
次のプログラムはほとんど同じことを行い、実際の違いはないようです。しかしそれは真実ではない。
#!/bin/bash
s=-1000
for (( i=0; i<1000000; i++ )); do
s=$((s+1))
done
echo "$s"
これが正しい方法です。 s + 1式はシェルによって評価され、変数に割り当てることができます。
#!/bin/bash
s=-1000
for (( i=0; i<1000000; i++ )); do
s=`expr "$s" + 1`
done
echo "$s"
ここの式は、組み込みシェルではなく外部Unixプログラムであるexprプログラムによって評価されます。したがって、単に1を足すことはできず、saプログラムを起動し、対応する出力を読み取り、変数に書き込む必要があります。プロジェクトを開始するには多くのリソースと時間が必要です。そして、このプログラムは1,000,000回実行されました。したがって、プログラムは以前よりはるかに遅くなります。それでもコードはうまくいきます。
#!/bin/bash -e
s=-1000
for (( i=0; i<1000000; i++ )); do
((s=s+1))
done
echo "$s"
-e フラグが設定されていない場合でも、プログラムは正常に動作します。ただし、s = -1のときに-eを設定すると((s = s + 1))が計算されます。 s = s + 1式は0と評価され((0))、終了コード> 0があり、これはシェルでエラーとして解釈され、シェルはプログラムを終了します。
-eフラグを設定する理由は、エラーを処理する最も簡単な方法です。エラーが発生した場合は停止します。