[ vs [[: bash スクリプトでどのようなものを使用しますか? [コピー]

[ vs [[: bash スクリプトでどのようなものを使用しますか? [コピー]

zshのマニュアルページは、test(別名[)セクションでこの項目を使用しないことを明示的に推奨し、読者が[[可能な場合はいつでもそれを使用することをお勧めします。

これ関連部品状態:

このコマンドは、POSIX と指定された拡張を実装しようとします。残念ながら、構文には本質的なあいまいさがあります。特に、テスト演算子に似た文字列に違いはありません。標準は、少数のパラメータ(最大4つ)の問題を解決しようとします。 5つ以上のパラメータについては互換性を信頼できません。[[可能な限り、これらのあいまいさが存在しない場合は、テストの構文を使用するようにユーザーにお勧めします。

同様のbashのアドバイスを見たようですが、bashのマニュアルページを見てみると、[どの形式(または)を使用するかについての「正式な」アドバイスが見つかりませんでした。[[(おそらく私が逃したのではないでしょうか?)

理由がありますか?「古いシェル」との下位互換性に加えて[、bashスクリプトに使用されますか?それとも別の理由でbashが[持続しますか?[[その他以前のバージョンとの互換性よりも?

答え1

しかし、まだいくつかの微妙な違いがあります。

#!/bin/bash

eg=whatever

if [ $eg == what* ]; then   # file glob test
    echo '[]'
fi

if [[ $eg == what* ]]; then   # pattern match test
    echo "[[]]"
fi      

現在のディレクトリに「whatever」というファイルがない場合、最初のテストは現在のディレクトリの内容のファイルglobと一致するためパスできませんが、2番目のテストは実際の文字列パターンの一致であるためです。

答え2

[十分なケースを好む理由は、さまざまなbashバージョンでより安定しているため[[です。[

バラよりman bash

31と互換性

設定されている場合、bashはバージョン3.1の[[条件付きコマンドの=〜演算子の引用符付き引数に動作を変更します。

32と互換性

設定されている場合、bashは[[条件付きコマンドの<および>演算子を使用すると、ロケール固有の文字列比較に関して動作をバージョン3.2の動作に変更します。 bash-4.1より前のBashバージョンはASCIIの組み合わせとstrcmp(3)を使用し、bash-4.1以降のバージョンは現在のロケールの組み合わせ順序とstrcoll(3)を使用します。

40と互換性があります

設定されている場合、bashは[[条件付きコマンド(前のトピックを参照)]の<および>演算子とコマンドリストの中断効果を使用すると、バージョン4.0のロケール固有の文字列比較で動作を変更します。

おそらく、背景を持つユーザーにとってより一般的ですksh

パフォーマンスに関する注意

'[[' は '[' より高速です。

  • 単一通貨の場合、速度差は次のとおりです。比較できる影響はありません、組み込みの「[」を好む必要があります。
  • より大きなループ構造にある場合は、「[」を「[[」に置き換えることを検討できます。

測定には、次の比較スクリプトを使用できます。

let upperBound=$1
echo "check [,  ${upperBound} iterations"
let i=0
time while [ $i -lt ${upperBound} ] ; do let i++ ; done

echo; echo;
echo "check [[, ${upperBound} iterations"
let i=0
time while [[ $i < ${upperBound} ]] ; do let i++ ; done

スクリプト結果の比較

確認[,1000回繰り返す

実際の0m0.031s
ユーザー0m0.028s
システム0m0.004s

[[、1000回繰り返し確認

実際の
0m0.000sユーザー0m0.000s
システム0m0.000s

関連情報