10周年のSPコンテンツ!

シェルスクリプトの[[と[の違い

どっちも動くから今まで適当に使ってたけど、気になったので調べてみた。 シェルというかbashね。 [[ は正規表現が使えるのが特に便利だけど後半で語られてるようなクオートやglob展開に関する差異もあるので気をつけて使いましょう。
プログラミング bash シェルスクリプト ベンチマーク
7
Yoshiaki Kawazu🐸ずん @kawaz
シェルスクリプトのテストコマンド [ と [[ の違い。 [[はbashの組み込みコマンドで、[は単にtestという外部コマンドの別名。なので必然[[の方が速い。 [[では比較演算子の<と>がエスケープなしで使える。[では¥<や¥>とする必要がある。 (続く…
Yoshiaki Kawazu🐸ずん @kawaz
(続き) [[では比較演算子の<と>がロケールに応じた辞書順比較になる。[ではASCII辞書順。 [[では=~で正規表現マッチングが使える。bashバージョン3以降の機能。 [[では演算子を"-f"のようにクオートするとエラーになる。]では問題ない。 こんなところかな。
Yoshiaki Kawazu🐸ずん @kawaz
違いを理解せずにどっちも大体動くから適当に使ってたけど、基本 [[ を使っておけば良さそうだということが分かった。
有為 @uwitenpen
@kawaz ((はどうなのかなーとおもったら[[の互換性無視したやつっぽい?
Yoshiaki Kawazu🐸ずん @kawaz
@uwitenpen ((は算術評価を行なって計算結果がゼロならステータス1を返すっていうコマンドですね。[[は条件式を評価する為のコマンドです。
Yoshiaki Kawazu🐸ずん @kawaz
. @uwitenpen 見た目似てるけど((と[[は算術評価と条件評価で全く別物。例を上げるとこんな感じか。 (( 1 + 1 ))→0 (( 1 - 1 ))→1 [[ 1 + 1 ]]→エラー [[ -d . ]]→0 (( -d . ))→エラー
Yoshiaki Kawazu🐸ずん @kawaz
[[は組み込みコマンドで[は外部コマンドだから当然[の方が遅いんだよな?という事を実際にベンチ取って確認してみたところMBA環境で、やっぱ3倍くらい違った。 https://t.co/dm21d0ra
加納智之 @tomyuk
@OrangeMorishita @tss_ontap @kawaz うーん。少なくともbash 4.x ではtestは組み込みです。それよりも、式の評価方法がちがう。もっとマニュアルよんだほうがいい
加納智之 @tomyuk
@OrangeMorishita @tss_ontap @kawaz [ と [[ を置き換えと思っていると、痛い目をみるよ
Yoshiaki Kawazu🐸ずん @kawaz
@tomyuk @OrangeMorishita @tss_ontap [[は文法で[とtestはコマンドという違いがありますが、挙動自体はどっちも真偽値評価するという点で違いは殆ど無いと思います。例えばどういうケースで痛い目を見ることになりそうでしょう?
加納智之 @tomyuk
@kawaz @OrangeMorishita @tss_ontap [[ は複合コマンド。[ は単なるコマンド。 [ expr ] と [[ expression ]] では評価法の定義が全く異なります。だからマニュアル読んで
加納智之 @tomyuk
@kawaz @OrangeMorishita @tss_ontap [[ $x == a* ]] と [ $x == a* ] では全然意味も違いますね
加納智之 @tomyuk
@kawaz @OrangeMorishita @tss_ontap [[ $x == a* ]] は x の内容に対して a* でのパターンマッチ。
Yoshiaki Kawazu🐸ずん @kawaz
@tomyuk @OrangeMorishita @tss_ontap あぁ、それは違いますね。クオートや展開について違いがあることは理解してて"-gt"て書けない辺りで軽く触れてましたが、まとめ見た人の為にそのへん詳しく追記しておいたほうが良いですね。指摘ありがとうございます。
加納智之 @tomyuk
@kawaz @OrangeMorishita @tss_ontap [ $x == a* ] だと、その場で a* を glob 展開してから文字列比較。なのでカレントディレクトリにaで始まるファイルが複数あればあぼ〜ん
Yoshiaki Kawazu🐸ずん @kawaz
@tomyuk @OrangeMorishita @tss_ontap そのあぼーんには同意wそういうの嫌いなので個人的には全ての文字列はクオートで囲むのがもう癖になってて[[の時だけ例外的に必要な部分だけクオートを意識して外すって感覚だったのでその辺の意識が甘かった(^^;
加納智之 @tomyuk
@kawaz @OrangeMorishita @tss_ontap ちなみに [] はクォートしたほうがいいことが多いけど、[[ ]] はクォートしないほうがいい。正規表現でみんなハマるパターン
Yoshiaki Kawazu🐸ずん @kawaz
@tomyuk @OrangeMorishita @tss_ontap クオートの使い分けはそのとおりですね。正規表現でハマるパターンはあとで書こうと思ってたことでした。 僕の理解が大きく間違ってた訳じゃないけど、人にまとめ見せるには配慮が足らなかったようです。補足どもです!
Yoshiaki Kawazu🐸ずん @kawaz
シェルスクリプトのような機微な記述が大切な話題はTwitterで書こうとするとどうしてもエッセンスのみでしたい補足が省略されて書いちゃいがちだから気をつけないとなー。やっぱ少し気合を入れてブログネタに仕上げるべきだった。

コメント

コメントがまだありません。感想を最初に伝えてみませんか?