Bashスクリプトで繰り返し処理と条件分岐を確実に身につけるなら、まず「for」ループと「if」文の基本構文を手元で書き、小さなサンプルを実行して動作を確認してください。最初はテキストエディタに簡単なコードを書き、実行権限を付与して ./script.sh と実行する流れを体験すると、構文エラーの見つけ方や変数の挙動もつかみやすくなります。以降の各セクションでは、具体的な書き方と実践例を step‑by‑step で示し、実際の業務シナリオに近いスクリプト作成までを丁寧に解説します。

目次

  • スクリプト基本構文
  • forループ基本
  • if文基本
  • forとif組み合わせ
  • デバッグとエラー対処

スクリプト基本構文

ファイル作成と実行権限

Bashスクリプトはプレーンテキストファイルとして作成します。ファイル名の拡張子は .sh が一般的ですが、必須ではありません。作成後は chmod +x script.sh で実行権限を付与し、./script.sh で実行します。

#!/bin/bash
# これはコメントです
echo "Hello, World!"

最初の行「#!/bin/bash」はシバングと呼ばれ、このスクリプトを Bash で解釈するように OS に指示します。シバングがない場合は、明示的に bash script.sh と呼び出す必要があります。

シバング(#!)の書き方

シバングの後に続くパスは、使用する Bash の絶対パスです。多くのディストリビューションでは /bin/bash が標準ですが、which bash で確認すると良いでしょう。パスが異なる環境では、#!/usr/bin/env bash と書くと、環境変数 PATH から最初に見つかった Bash を使用します。

コメントと変数

コメントは # から行末までです。変数は VAR=value の形式で代入し、参照するときは $VAR または ${VAR} です。特別な変数として $0 (スクリプト名)、$1$9 (位置パラメータ)、$# (パラメータ数)、$*@ (全パラメータ) があります。

#!/bin/bash
GREETING="Hello"
NAME=$1
echo "${GREETING}, ${NAME}!"

上記スクリプトを ./script.sh Alice と実行すると Hello, Alice! と表示されます。

バージョン比較表

Bash バージョンリリース年主な追加機能
3.02004配列の強化、正規表現演算子 =~
4.02009連想配列、coprocmapfile
5.02019変数の長さ制限緩和、BASH_ARGV0printf%q 拡張

(出典: GNU Bash Reference Manual)
注:配列の要素数上限は Bash 3.2 以降で 32767 個です。(出典: Bash FAQ E15)

forループ基本

基本構文とリスト形式

最もシンプルな for ループは、スペースで区切られたリストを順に処理します。

#!/bin/bash
for fruit in apple banana cherry; do
    echo "I like $fruit"
done

この例では fruit 変数に applebananacherry が順番に入り、ループ内の echo が実行されます。

Cスタイルforループ

C 言語風の初期化・条件・増減式を使った書き方も可能です。この場合は二重括弧 (( )) を使用します。

#!/bin/bash
for (( i=0; i<5; i++ )); do
    echo "Count: $i"
done

初期式 i=0、条件式 i<5、増減式 i++ がセミコロンで区切られます。< は HTML でエスケープしていますが、実際のスクリプトでは < として書きます。

範囲指定とstep

波括弧展開を使うと、数列や文字列の範囲を簡単に指定できます。また、{start..end..step} 形式でステップを設定することも可能です(Bash 4.0 以降)。

#!/bin/bash
# 1 から 10 まで 2 おきに出力
for i in {1..10..2}; do
    echo "$i"
done

結果は 1 3 5 7 9 となります。ステップを省略すると 1 おきになります。

if文基本

基本構文とtestコマンド

if 文は条件が真(終了ステータス 0)ならば then 以降のブロックを実行します。条件評価には組み込みコマンド test またはそのエイリアス [ … ] を使います。

#!/bin/bash
VAR=10
if [ $VAR -eq 10 ]; then
    echo "VAR is 10"
fi

ここでは -eq が整数の等価比較です。スペースは必ず必要で、[ $VAR -eq 10 ] のように括弧内に空白を入れます。

比較演算子(数値・文字列)

数値比較では -eq (等)、-ne (不等)、-lt (未満)、-le (以下)、-gt (超過)、-ge (以上) を使います。文字列比較では = (等価)、!= (不等)、< (辞書順未満)、> (辞書順超過) が利用可能です。なお、[ … ] 内での <> はエスケープが必要です。

#!/bin/bash
STR1="apple"
STR2="banana"
if [ "$STR1" \< "$STR2" ]; then
    echo "$STR1 comes before $STR2"
fi

ダブルクォートで変数を囲むと空白や特殊文字を含む場合でも安全です。

複数条件の結合

複数の条件を組み合わせるには論理演算子 && (AND)、|| (OR) を使います。これによりネストを減らし、可読性を向上させます。

#!/bin/bash
NUM=15
if [ $NUM -ge 10 ] && [ $NUM -le 20 ]; then
    echo "NUM is between 10 and 20 inclusive"
fi

上記は NUM が 10 以上かつ 20 以下であるときだけメッセージを出します。

forとif組み合わせ

偶数のみ出力サンプル

for ループの中で if 文を使うと、特定の条件に合う要素のみを処理できます。ここでは 1 から 10 までの数のうち、偶数だけを出力します。

#!/bin/bash
for i in {1..10}; do
    if [ $(( i % 2 )) -eq 0 ]; then
        echo "$i is even"
    fi
fi
done

剰余演算子 % を使って 2 で割った余りが 0 かを判定しています。

ファイルリスト処理

ディレクトリ内のファイル名を取得して、拡張子が .log のものだけを処理する例です。

#!/bin/bash
for file in *.log; do
    if [ -f "$file" ]; then
        echo "Processing $file"
        # ここでは単にファイルサイズを表示
        wc -l "$file"
    fi
done

ワイルドカード *.log がマッチしない場合でもループは一度だけ実行されますが、[ -f "$file" ] で実際にファイルかどうかを確認しています。

ネストループ例

2 次元の座標を出力するネストした for ループの例です。

#!/bin/bash
for x in {1..3}; do
    for y in {1..3}; do
        echo "($x,$y)"
    done
done

これにより (1,1) から (3,3) までの組み合わせが順番に表示されます。

デバッグとエラー対処

set -x と set -v

スクリプトの実行過程をトレースしたいときは set -x を有効にします。これにより各コマンドが実行される前にそのコマンド行が標準エラーに表示されます。同様に set -v は入力行をそのまま表示します(変数展開前)。

#!/bin/bash
set -x
VAR=5
echo $VAR
set +x

トレースを止めたいときは set +x とします。実際の開発ではバグの切り離しに非常に有効です。

シェルチェックの活用

shellcheck は Bash スクリプトの静的解析ツールで、文法ミスやベストプラクティス違反を検出します。多くの Linux ディストリビューションのパッケージマネージャでインストール可能です。

$ shellcheck myscript.sh

実行すると、たとえば未クォート変数や不要なセミコロンなどの警告が出ます。CI パイプラインに組み込むと品質維持に役立ちます。

よくあるエラーと対処

  • 「command not found」:パスが通っていないコマンドを呼び出している。絶対パスを使うか、PATH を確認。
  • 「[: missing `]'`」: test コマンドの括弧の対応がずれている。スペースと括弧の数をチェック。
  • 「Bad substitution」: 変数展開の構文が間違っている。${VAR} の形を確認。
  • 「overflow in arithmetic expression」: 整数演算でオーバーフロー。Bash の整数範囲は符号付き 64 ビットまで。

これらのエラーはほとんどが入力ミスによるものなので、エラーメッセージをよく読んで該当箇所を修正すれば解決します。

よくある質問

Q1: Bash スクリプトで改行を含む出力をしたいときはどうすればいいですか?

A: echo -e を使うとエスケープシーケンスが解釈されます。例:echo -e "Line1\nLine2"。あるいは printf を使うとよりポータブルです:printf "Line1\\nLine2\\n"

Q2: 配列の要素数を取得する方法は?

A: 配列名に # を付けると長さが取得できます。例:arr=(a b c); echo ${#arr[@]} は 3 を出力します。

Q3: サブシェルと現在のシェルの変数スコープの違いは?

A: カッコ ( ) で囲んだコマンド列はサブシェルで実行され、そこでの変数変更は親シェルに反映されません。

【編集・制作ポリシー】
本記事はInfra Academy編集部が各ベンダー公式ドキュメント・エンジニア監修をもとに作成しています。インフラ・クラウド構築は環境により異なります。本番環境への適用前に必ずテストを実施してください。情報の正確性には万全を期していますが、最新情報は各公式ドキュメントをご確認ください。
編集ポリシーはこちら
ABOUT ME
たから
フリーランスIT講師/エンジニア。 ◆経験:IT講師/インフラエンジニア/PM/マネジメント/採用/運用・保守・構築・設計 ◆取得資格:CCNA/CCNP/LPIC-1/AZ-900//サーティファイC言語/情報処理技術者 ◆サイドビジネス:アパレル事業/複数のWEBメディアを運営