shellの条件分岐の[と[[

linux

[ はPOSIX準拠のtestコマンド。[[ はその拡張でdashなどではサポートされていない。

$ which [
/usr/bin/[

$ man [
TEST(1)

NAME
       test - check file types and compare values

SYNOPSIS
       test EXPRESSION
       test
       [ EXPRESSION ]
       [ ]
       [ OPTION
...

あくまでコマンドなので前後にスペースを空ける必要がある。

if [ -e ./foo.txt ]; then
    echo "file exists"
else
    echo "no file exists"
fi

一般的なプログラミング言語と異なり、0がtrueでそれ以外がfalse。

$ true; echo $?
0

$ false; echo $?
1

if文を使わなくても条件分岐できる。

$ [ -e ./foo.txt ] && echo "file exists" || echo "no file exists"
file exists

==/!=で値の一致を判定できるが、[ では次のように空の変数をそのまま比較するとオペレータが存在しなくなってエラーになる。 [[ では問題ない。

$ unset XXX
$ [ $XXX == aaa ] && echo $?
bash: [: ==: unary operator expected

$ [[ $XXX != aaa ]] && echo $?
0

$ [ "$XXX" != aaa ] && echo $?
0

なお大小比較を</>で行ってしまうとリダイレクトになってしまい正しい結果が得られない。

$ [ 1 > 100 ] && echo $?
0

$ [ 1 < 0 ] && echo $?
bash: 0: No such file or directory

$ [ 1 -gt 0 ] && echo $?
0

[[だとワイルドカードや正規表現が使える。

$ [[ "$XXX" == *aa ]] && echo $?
0

$ [[ "$XXX" =~ ^a+.*a$ ]] && echo $?
0

-a/-oでAND/ORを記述できる。[[では&&/||も使える。

$ [ true -o false -a false ] && echo $?
0

$ ([ true ] || [ false ] && [ false ]) && echo $?
0

$ [[ true || false && false ]] && echo $?
0