本記事では、bashのif文でand, or, notなどの条件式を使う方法を解説します。
if文
bashにおけるif文は、条件を評価してその結果に基づいて処理を分岐させます。基本的な構造として、条件が真と評価された場合の処理をthenキーワードの後に記述します。また、条件が偽の場合の処理をelseで指定することも可能です。
条件式
bashでは主に以下の2つの方法で条件式を記述できます。
- testコマンド(または[コマンド)- シェルに組み込まれた条件評価コマンドで、ファイルの存在や文字列の比較などを行います
- [[(拡張テスト構文)- bashの拡張機能で、testコマンドの機能に加えて、パターンマッチングなどの高度な操作が可能です
if文中での条件式
条件式はif文と組み合わせて使用します。以下のような書き方があります。
# testコマンドを使用 - 条件を評価する最も基本的な方法
if test -f "$file"; then
echo "ファイルが存在します"
fi
# [コマンド(角括弧)を使用 - testと同等の機能を持つ代替構文
if [ -f "$file" ]; then
echo "ファイルが存在します"
fi
# [[(二重角括弧)を使用 - Bash拡張構文で、より柔軟な条件式が書ける
if [[ -f "$file" ]]; then
echo "ファイルが存在します"
fi
ここで「-f」は「ファイルが存在し、通常ファイルである」ことをテストするための演算子です。
testコマンドと拡張テスト構文[[の違い
- 構文と互換性
- testコマンド(または[): POSIX標準に準拠しており、ほとんどのシェルで使用可能です。移植性が高いスクリプトを書く場合に適しています。
- [[構文: bash、ksh、zshなどの特定のシェルでのみ使用可能な拡張機能です。より強力ですが、移植性は低くなります。
- 単語分割と変数展開
- testコマンド: 変数が展開される際に単語分割が発生するため、空白を含む変数は引用符で囲む必要があります。
- [[構文: 変数が単語分割されないため、引用符を省略しても安全な場合があります(ただし、常に引用符を使用するのが良い習慣です)。
- パターンマッチング
- testコマンド: 正規表現はサポートしていません。
- [[構文: =~演算子を使用して正規表現パターンマッチングが可能です。また、や?などのワイルドカードもサポートしています。
- 論理演算子
- testコマンド: a(AND)やo(OR)を使用しますが、これらは非推奨となっています。
- [[構文: &&(AND)や||(OR)を直接構文内で使用でき、より読みやすいコードになります。
例えば、文字列のパターンマッチングでは
# [[を使用した正規表現マッチング
if [[ "$string" =~ ^[0-9]+$ ]]; then
echo "文字列は数字のみで構成されています"
fi
# [[を使用したワイルドカードマッチング
if [[ "$filename" == *.txt ]]; then
echo "テキストファイルです"
fi
可能な限り[[構文を使用することで、より安全で読みやすいスクリプトが書けますが、他のシェルとの互換性が必要な場合はtestコマンドを使用することも検討してください。
and
bashでAND条件(複数の条件をすべて満たす)を表現するには、以下の方法があります:
- &&演算子を使用する – 左側の条件が真の場合のみ右側を評価し、両方が真の場合に全体が真になる
- [[ ]]内で&&を使用する – 拡張テスト構文内での論理AND
- a演算子を使用する(非推奨)- 古い形式の論理AND演算子
# 方法1: 複数のtest条件を && で連結
if [ -f "$file" ] && [ -r "$file" ]; then
echo "ファイルが存在し、読み取り可能です"
fi
# 方法2: [[ ]] 内で && を使用
if [[ -f "$file" && -r "$file" ]]; then
echo "ファイルが存在し、読み取り可能です"
fi
「-r」は「ファイルが読み取り可能である」ことをテストする演算子です。上記の例では、ファイルが存在し、かつ読み取り可能である場合にのみメッセージが表示されます。
注意: -a演算子は現在非推奨とされています。POSIX互換性の理由から、&&演算子や[[ ]]構文を使用することが推奨されています。将来のbashバージョンでは、-aは削除される可能性があります。
or
bashでOR条件(いずれかの条件を満たす)を表現するには、以下の方法があります:
- ||演算子を使用する – 左側の条件が偽の場合のみ右側を評価し、どちらか一方が真の場合に全体が真になる
- [[ ]]内で||を使用する – 拡張テスト構文内での論理OR
- o演算子を使用する(非推奨)- 古い形式の論理OR演算子
# 方法1: 複数のtest条件を || で連結
if [ -f "$file" ] || [ -d "$file" ]; then
echo "ファイルかディレクトリが存在します"
fi
# 方法2: [[ ]] 内で || を使用
if [[ -f "$file" || -d "$file" ]]; then
echo "ファイルかディレクトリが存在します"
fi
「-d」は「ディレクトリが存在する」ことをテストする演算子です。上記の例では、ファイルまたはディレクトリが存在する場合にメッセージが表示されます。
注意: -o演算子も-aと同様に非推奨とされています。||演算子や[[ ]]構文を使用することが推奨されています。
not
条件を否定するには、以下の方法があります:
- !演算子を使用する – 条件の論理否定を行う(真を偽に、偽を真にする)
# ファイルが存在しない場合
if [ ! -f "$file" ]; then
echo "ファイルが存在しません"
fi
# [[ ]]を使用する場合
if [[ ! -f "$file" ]]; then
echo "ファイルが存在しません"
fi
「!」演算子は後に続く条件の結果を反転させます。上記の例では、ファイルが存在しない場合にメッセージが表示されます。
応用例
複数の条件を組み合わせた例を見てみましょう。
#!/bin/bash
file="example.txt"
backup="backup.txt"
permissions="644"
if [ ! -f "$file" ] || ([ -f "$file" ] && [ ! -r "$file" ]) && ([ ! -f "$backup" ] || [ -w "$backup" ]); then
echo "処理実行: 条件一致"
fi
このスクリプトでは、以下の複雑な条件判定を行っています。
- メインファイルが存在しない(-fはファイルが存在するかを判定)、または
- メインファイルが存在するが読み取り権限がない(-rは読み取り権限があるかを判定)、かつ
- バックアップファイルが存在しないか、バックアップファイルが書き込み可能(-wは書き込み権限があるかを判定)
まとめ
bashのif文で条件式を使用する際のポイントをまとめます。
- 複数条件の「AND」には&&演算子を使用する(-aは非推奨)
- 複数条件の「OR」には||演算子を使用する(-oは非推奨)
- 条件の否定には!演算子を使用する
- 複雑な条件には[[ ]]拡張テスト構文を使用すると読みやすく、機能も豊富
- 変数は常に引用符で囲む(”$variable”)ことでスペースを含む値も正しく処理できる
これらの知識を活用して、より堅牢で柔軟なbashスクリプトを作成してください。条件分岐を適切に使うことで、エラー処理や入力検証などの重要な機能を実装できます。