それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

bashの似てて紛らわしいもの [[ / ((

似てて紛らわしいものシリーズ [[ / ((

bash の記述で初心者泣かせの、似てて紛らわしかったり、どう使っていいかわからなかったり、読み方を間違えてパニックになる記号について。今回は [[ / ((について

[[ / (( の違い

[[ / (( は if 文の条件判断の中で使われることが多いですが、それ単体でコマンドです。

これらはコマンドなので終了ステータスを持ちます。

  • [[ は new スタイルの testコマンドです。これで文字列比較やります。
  • (( は new スタイルの数値計算です。これで数値比較やります。

どちらも if 文でよく使われる

どちらも、if 文のなかで使われることが多いんですが、違うものです。似ているものだけど違うものです。

一番大きな違いは 以下の点にあります。

  • [[ は文字列比較で使われる
  • (( は数値比較で使われる。
[[ 0 == 0 ]] # 文字列として比較
(( 0 == 0 )) # 数値として比較

なぜんこんなことを書くのか。

==で数字の一致チェックだと正しく動く、数字文字列比較も数値比較も全くおなじに見えるからです。

どちらも true になる比較が次の例です。

[[ での等価比較
var=0
if [[ $var == 0 ]] ; then
    echo yes
fi
(( での0と等価比較
var=0
if (( $var == 0 )) ; then
    echo yes
fi

大小比較すると明確に違う

var=1000
[[ $var > 11 ]] ; echo $? # exit code 1 つまり false
(( $var > 11 )) ;echo $?  # exit code 0 つまり true
  • [[ の比較は辞書順。1000 > 11 は11 が大きくなる。
  • (( の比較は数値順。1000 > 11 は1000 が大きくなる。

ここは油断すると酷い目に遭うので注意が必要。 原理をしらず== で比較で使ってた。

わたしは数年前に手痛い目にあって覚えた・・・辛い。

組み合わせたらどうなるのか?

組み合わせられない。よくわからないことになる。試したけどちょっと何ががなんだか。

$ (( [[ 0 ]]  ));echo $? #=> 1 / false
-bash: ((: [[ 0 ]]  : 構文エラー: オペランドが予期されます (エラーのあるトークンは "[[ 0 ]]  ")
1
$ [[ (( 1/0 )) ]]; echo $?

0で除算がエラーにならない??もうわけわからんね・・・