Bashの[ ] vs [[ ]]: シングル vs ダブルブラケット
bashの[ ](test)と[[ ]]の違いを理解。それぞれの使い分け、POSIX互換性、== vs =の一般的な間違いを解説します。
Deprecated Syntax
詳細な説明
シングルブラケット[ ] vs ダブルブラケット[[ ]]
[ ]と[[ ]]の選択は、シェルスクリプトで最も混乱しやすい側面の一つです。見た目は似ていますが、動作はかなり異なります。
[ ] — testコマンド
[ ]は実際にはtestコマンドです。シェル構文ではなく、通常のコマンドです:
# これらは同等:
[ "$var" = "hello" ]
test "$var" = "hello"
[ ]のルール:
- 変数は必ずクォート:
[ "$var" = "value" ] - 文字列比較には
=を使用(==ではない) - 数値比較には
-eq、-lt、-gtを使用 - パターンマッチングや正規表現なし
&&と||は外側に:[ cond1 ] && [ cond2 ]
[[ ]] — Bashキーワード
[[ ]]はBash/Zsh/Kshの組み込みキーワードで、追加機能があります:
# ワードスプリッティングなし — クォートはオプション(推奨はする)
[[ $var = "hello" ]]
# ==でパターンマッチング
[[ $file == *.txt ]]
# =~で正規表現マッチング
[[ $email =~ ^[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]+$ ]]
# 内部で論理演算子
[[ $a -gt 0 && $b -lt 100 ]]
よくある間違い: [ ]での==
# 間違い: ==は[ ]ではPOSIXではない
if [ "$var" == "value" ]; then # bashでは動作するがshでは動作しない
# [ ]での正解:
if [ "$var" = "value" ]; then
# [[ ]]での正解:
if [[ "$var" == "value" ]]; then
比較表
| 機能 | [ ] |
[[ ]] |
|---|---|---|
| POSIX互換 | はい | いいえ(bash/zsh/ksh) |
| ワードスプリッティング | あり(クォート必須) | なし |
| パターンマッチング | なし | == *.txt |
| 正規表現 | なし | =~ regex |
| 論理演算子 | 外部&&/` |
|
| 文字列比較 | = |
=または== |
推奨
- Bashスクリプトでは
[[ ]]を使用(#!/bin/bashシェバン付き) - POSIX互換性が必要な場合のみ
[ ]を使用(#!/bin/sh) [ ]では常に変数をクォートしてワードスプリッティングを防止
ユースケース
シェルスクリプトでの条件ロジックの記述、ユーザー入力の検証、ファイルの存在と種類のチェック、文字列のパターンマッチング。ポータブルまたは高度なマッチングを使用するシェルスクリプトを書く人にとって、違いを理解することが不可欠です。