こんにちは、かつコーチです。
前回は、if文の基本形と、数値比較・文字列比較の演算子の違いを解説しました。
条件式の中でさらっと使っていた[ ]ですが、実はtestコマンドや[[ ]]という仲間があり、それぞれ挙動が微妙に異なります。
「なぜ現場のスクリプトには[[ ]]を使うものと[ ]を使うものが混在しているのか」と疑問に思った方もいるはずです。
今回は、この3つの違いを比較しながら、どれを選ぶべきかの判断軸を明確にしていきます。
test・[ ]・とは?
条件を判定する3つの道具
testとは、条件が真か偽かを判定するコマンドの名前そのものです。
[ ]は、このtestコマンドの別名(エイリアス)として用意された、より簡潔に書ける記法です。
[[ ]]は、bash独自に拡張された、より高機能で安全な条件判定の構文です。
判定する道具という意味では3つとも同じ役割ですが、精度や機能が異なる「進化した物差し」だとイメージすると分かりやすいです。
昔ながらの目盛りだけの物差し(test・[ ])と、誤差を自動補正してくれる高精度な物差し([[ ]])の違いに近いものがあります。
なぜ違いを知る必要があるのか
[ ]は歴史的な経緯から他のシェル(shなど)との互換性を保つために存在し、[[ ]]はbashやzshなど一部のシェルでしか使えません。
互換性を優先するスクリプトでは[ ]が、bash専用と割り切れるスクリプトでは[[ ]]が向いているというように、目的によって使い分けが必要になります。
3つの記法の比較
基本構文の違い
まずは同じ条件を、3つの書き方で比較してみます。
#!/bin/bash
count=10
# testコマンド
if test "$count" -gt 5; then
echo "testで判定:5より大きい"
fi
# [ ](testのエイリアス)
if [ "$count" -gt 5 ]; then
echo "[ ]で判定:5より大きい"
fi
# [[ ]](bash拡張構文)
if [[ $count -gt 5 ]]; then
echo "[[ ]]で判定:5より大きい"
fi
3つとも同じ結果になりますが、[[ ]]だけは変数をダブルクォートで囲まなくても、単語分割によるエラーが起きにくいという違いがあります。
比較表:test / [ ] /
互換性が求められる環境(/bin/shで動かす前提のシステムスクリプトなど)では[ ]、それ以外の通常のbashスクリプトでは[[ ]]を選ぶのが現場での一般的な判断軸です。
どちらを選べばいいか:判断フロー
- 対象OSやDockerイメージが
sh(dashなど)で動く可能性がある →[ ]を使う - Ubuntu 26.04 LTSのbash前提で、自分(またはチーム)だけが使うスクリプト →
[[ ]]を使う - 迷ったら、まずは
[[ ]]を使い、互換性の指摘を受けたら[ ]に置き換える
比較演算子の一覧
数値比較演算子
| 演算子 | 意味 | 例 |
|---|---|---|
-eq | 等しい | [ "$a" -eq "$b" ] |
-ne | 等しくない | [ "$a" -ne "$b" ] |
-gt | より大きい | [ "$a" -gt "$b" ] |
-ge | 以上 | [ "$a" -ge "$b" ] |
-lt | より小さい | [ "$a" -lt "$b" ] |
-le | 以下 | [ "$a" -le "$b" ] |
文字列比較演算子
| 演算子 | 意味 | 例 |
|---|---|---|
= | 等しい | [ "$a" = "$b" ] |
!= | 等しくない | [ "$a" != "$b" ] |
-z | 空文字である | [ -z "$a" ] |
-n | 空文字でない | [ -n "$a" ] |
[[ ]]の中では、==を使うとワイルドカードによるパターンマッチも可能になります。
filename="report.txt"
if [[ $filename == *.txt ]]; then
echo "txtファイルです"
fi
よくあるつまずきポイント:スペースの数え間違い
私が新人時代、[ ]の中のスペースを詰めて書いてしまい、原因が分からず1時間近く悩んだことがあります。
❌ Before:かっこと条件式の間にスペースがない
count=10
if [$count -gt 5]; then
echo "5より大きい"
fi
bash: [10: command not found
[はtestコマンドの別名であり、コマンドである以上、引数との間には必ずスペースが必要です。
[$countのようにくっつけて書くと、シェルは[10という1つの(存在しない)コマンド名として解釈してしまいます。
✅ After:かっこと条件式の間に必ずスペースを入れる
count=10
if [ "$count" -gt 5 ]; then
echo "5より大きい"
fi
[の後ろと]の前、両方にスペースが必要です。
このルールを知らないと「unary operator expected(単項演算子が期待されている)」といった別のエラーに遭遇することもあるので、[ ]を書くときは常にスペースの有無を意識してください。
応用・一歩先の使い方
ファイル判定オプションとの組み合わせ
test・[ ]・[[ ]]はいずれも、ファイルの種類を判定するオプションと組み合わせて使えます。
if [[ -d "/var/backup" ]]; then
echo "ディレクトリが存在します"
fi
if [[ -x "/usr/bin/bash" ]]; then
echo "実行可能なファイルです"
fi
-dはディレクトリ判定、-xは実行権限の有無を判定するオプションで、SH02で扱った実行権限の確認にも応用できます。
まとめ
この記事のポイント
test・[ ]・[[ ]]は判定の役割は同じだが、対応範囲や安全性が異なる- 互換性重視なら
[ ]、bash専用の現代的なスクリプトなら[[ ]]を選ぶ [はコマンドの別名なので、前後に必ずスペースを入れる- 数値比較は
-eq系、文字列比較は=系の演算子を使う
次に読むべき記事
次回は、条件分岐と並んでよく使う繰り返し処理として、for文・whileループの書き方を解説します。
→ 次の記事:for文・whileループで繰り返し処理をする
タグ: Shell, 中級者向け, 制御構文