Bashスクリプト基礎入門|変数・条件分岐・ループを完全マスター

Linux/Unix環境で自動化を実現するならBashスクリプトが最適です。変数宣言・条件分岐・ループ処理を正しく使いこなせば、日々の運用作業を数分で完了させられます。本記事では実務で即座に活用できる具体的な書き方を、実行可能なサンプルコードと共に解説します。初心者でも1日で基本構文を習得できる内容です。


目次


Bashスクリプトとは何か

Bash(Bourne-Again SHell)はLinux/Unixシステムで標準的に利用されるシェルです。Bashスクリプトはこのシェルで実行可能なコマンド群をテキストファイルにまとめたプログラムであり、以下の特徴があります。

  • 軽量性:システムリソースをほとんど消費せず、即座に実行可能
  • 柔軟性:コマンドライン操作をそのままスクリプト化できる
  • 自動化:定型業務を自動実行し、人的ミスを排除
  • 移植性:主要なUnix系OSで動作(ただし一部の機能はOS依存あり)

特にサーバー運用やDevOps業務では、Bashスクリプトがなくてはならない存在です。例えばログファイルの整形、バックアップ処理、システム監視など、あらゆる場面で活躍します。

公式ドキュメントによると、BashはPOSIX標準に準拠しており、シェルスクリプトの事実上の標準言語となっています(出典: GNU Bash Manual)。


実行環境の準備と基本設定

1. 実行環境の確認

Bashスクリプトを実行するには以下の環境が必要です。

  • Linux/Unix系OS(Ubuntu、CentOS、macOSなど)
  • Bashシェル(通常はデフォルトでインストール済み)
  • テキストエディタ(vim、nano、VS Codeなど)

現在のBashバージョンを確認するには以下のコマンドを実行します。

bash --version

出力例: GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

バージョンが表示されればBashは利用可能です。macOSの場合はデフォルトでBash 3.2がインストールされていますが、Homebrew経由で最新版にアップグレードできます。

2. スクリプトファイルの作成

スクリプトファイルは通常のテキストファイルで作成します。拡張子は「.sh」が一般的ですが、必須ではありません。以下の手順で作成します。

実行手順:
1. テキストエディタで新規ファイルを作成
2. 以下の内容を入力
3. ファイル名を「hello.sh」として保存
4. 実行権限を付与
5. 実行
#!/bin/bash

これはコメントです

echo "Hello, World!"

ファイルを保存後、実行権限を付与します。

chmod +x hello.sh

実行

./hello.sh

出力: Hello, World!

注意点:

  • Shebang(#!/bin/bash)は必須です。これによりOSがBashを使用してスクリプトを実行します。
  • 実行権限(chmod +x)がなければ「Permission denied」エラーが発生します。
  • Windows環境で実行する場合はWSL(Windows Subsystem for Linux)を使用してください。

3. 実行方法の種類

Bashスクリプトには主に3つの実行方法があります。

実行方法説明使用シーン
直接実行(./script.sh)実行権限を付与し、./で実行ローカル環境での実行に最適
bashコマンドで実行(bash script.sh)実行権限がなくても実行可能一時的な実行やテストに便利
sourceコマンドで実行(source script.sh)現在のシェル環境で実行(変数が引き継がれる)環境変数の設定などに使用

変数の宣言と活用方法

Bashスクリプトにおける変数は、データを一時的に保存するための仕組みです。他言語と異なり、変数宣言時に型を指定する必要はありません。

1. 変数の基本的な使い方

変数の宣言と代入は以下のように行います。

# 変数の宣言と代入
NAME="John Doe"
AGE=30

変数の参照($を付ける)

echo "Name: $NAME" echo "Age: $AGE"

注意点:

  • 変数名には大文字・小文字の区別があります(NAMEとnameは別の変数)
  • 変数名には数字・アンダースコア・アルファベットのみ使用可能
  • 変数名の先頭に数字は使用できません
  • スペースを含む値を代入する場合はダブルクォーテーションで囲む

2. 変数のスコープ

Bashの変数には2種類のスコープがあります。

スコープタイプ説明
ローカル変数関数内でのみ有効な変数local VAR="value"
グローバル変数スクリプト全体で有効な変数VAR="value"

関数内でローカル変数を宣言するには「local」キーワードを使用します。

#!/bin/bash

GLOBAL_VAR="I'm global"

function test_scope {
    local LOCAL_VAR="I'm local"
    echo "Inside function: $LOCAL_VAR"
    echo "Inside function: $GLOBAL_VAR"
}

test_scope
echo "Outside function: $GLOBAL_VAR"

echo "Outside function: $LOCAL_VAR" # これはエラー(LOCAL_VARは関数内でのみ有効)

3. 特殊な変数

Bashにはシステムによって自動的に設定される特殊変数が多数存在します。主なものを以下に示します。

変数名説明使用例
$0スクリプト名echo "Script name: $0"
$1, $2, …引数($1は1番目の引数)echo "First argument: $1"
$#引数の総数echo "Number of arguments: $#"
$@すべての引数(配列として扱う)for arg in "$@"; do echo "$arg"; done
$?直前のコマンドの終了ステータス(0=成功、非0=失敗)if [ $? -eq 0 ]; then echo "Success"; fi
$$現在のプロセスIDecho "Process ID: $$"

これらの特殊変数を活用することで、柔軟なスクリプトを作成できます。

4. 変数の展開と置換

Bashでは変数に対して様々な展開操作が可能です。

構文説明
${VAR}変数の値を参照echo ${NAME}
${VAR:-default}変数が未設定または空の場合にデフォルト値を使用echo ${NAME:-Guest}
${VAR:=default}変数が未設定または空の場合にデフォルト値を代入して使用echo ${NAME:=Guest}
${VAR:?error}変数が未設定または空の場合にエラーを表示echo ${NAME:?Name is required}
${VAR%pattern}末尾のパターンに一致する部分を削除echo ${FILE%.txt}
${VAR#pattern}先頭のパターンに一致する部分を削除echo ${PATH#*:}

これらの展開機能を使いこなすことで、より堅牢なスクリプトを作成できます。


条件分岐(if文・case文)の完全ガイド

条件分岐はプログラムの流れを制御する重要な機能です。Bashではif文とcase文の2種類の条件分岐が使用できます。

1. if文の基本構文

if文の基本構文は以下の通りです。

if [ 条件式 ]; then
    # 条件が真の場合の処理
elif [ 別の条件式 ]; then
    # elifの条件が真の場合の処理
else
    # いずれの条件も真でない場合の処理
fi

注意点:

  • 条件式は角括弧[]で囲む(スペースに注意)
  • thenとfiはそれぞれ改行またはセミコロンで区切る
  • 条件式の比較演算子には特定の書式がある

2. 条件式の比較演算子

Bashにおける主な比較演算子は以下の通りです。

演算子説明文字列比較例数値比較例
= または ==等しい[ "$str1" = "$str2" ]
!=等しくない[ "$str1" != "$str2" ]
-eq等しい(数値)[ $num1 -eq $num2 ]
-ne等しくない(数値)[ $num1 -ne $num2 ]
-ltより小さい(数値)[ $num1 -lt $num2 ]
-le以下(数値)[ $num1 -le $num2 ]
-gtより大きい(数値)[ $num1 -gt $num2 ]
-ge以上(数値)[ $num1 -ge $num2 ]
-z文字列が空[ -z "$str" ]
-n文字列が空でない[ -n "$str" ]
-fファイルが存在する[ -f "/path/to/file" ]
-dディレクトリが存在する[ -d "/path/to/dir" ]

3. 実践的なif文の例

以下に実務で役立つif文の例を示します。

ファイルの存在確認

#!/bin/bash

FILE="/etc/passwd"

if [ -f "$FILE" ]; then
    echo "ファイル $FILE は存在します"
    echo "ファイルサイズ: $(du -h "$FILE" | cut -f1)"
else
    echo "ファイル $FILE は存在しません"
    exit 1
fi

引数の検証

#!/bin/bash

if [ $# -eq 0 ]; then
    echo "エラー: 引数が必要です"
    echo "使用法: $0 "
    exit 1
fi

USERNAME=$1

if ! id "$USERNAME" &>/dev/null; then
    echo "エラー: ユーザー $USERNAME は存在しません"
    exit 1
fi

echo "ユーザー $USERNAME のホームディレクトリ: $(eval echo ~$USERNAME)"

数値の比較

#!/bin/bash

read -p "年齢を入力してください: " AGE

if [ "$AGE" -lt 0 ]; then
    echo "エラー: 年齢は正の数で入力してください"
elif [ "$AGE" -lt 13 ]; then
    echo "子供"
elif [ "$AGE" -lt 20 ]; then
    echo "ティーンエイジャー"
elif [ "$AGE" -lt 65 ]; then
    echo "大人"
else
    echo "シニア"
fi

4. case文の活用

case文は複数の条件分岐をシンプルに記述できる構文です。if文よりも読みやすい場合があります。

基本構文:

case 変数 in
    パターン1)
        # 処理1
        ;;
    パターン2)
        # 処理2
        ;;
    *)
        # デフォルト処理
        ;;
esac

注意点:

  • 各パターンの終わりには;;が必要
  • *)はデフォルト処理(switch文のdefaultに相当)
  • パターンにはワイルドカード(*、?、[])が使用可能

実践例:

#!/bin/bash

read -p "OSを入力してください (linux/mac/windows): " OS

case $OS in
    linux|Linux)
        echo "Linuxシステムです"
        ;;
    mac|Mac)
        echo "macOSシステムです"
        ;;
    windows|Windows)
        echo "Windowsシステムです"
        ;;
    *)
        echo "不明なOSです"
        exit 1
        ;;
esac

case文は特にコマンドライン引数の処理や、ユーザー入力のバリデーションに適しています。


ループ処理(for・while・until)の実践テクニック

ループ処理は同じ処理を繰り返し実行する際に使用します。Bashでは主に3種類のループ構文が利用できます。

1. forループ

forループはリストや範囲の要素を順に処理する際に使用します。

基本構文

for 変数 in リスト; do
    # 処理
done

リストからのループ

#!/bin/bash

文字列のリスト

for FRUIT in apple banana orange; do echo "フルーツ: $FRUIT" done

配列のループ

FRUITS=("りんご" "バナナ" "オレンジ") for FRUIT in "${FRUITS[@]}"; do echo "フルーツ: $FRUIT" done

コマンドの出力をループ

for FILE in $(ls *.txt); do echo "テキストファイル: $FILE" done

範囲を使ったループ

#!/bin/bash

0から9までループ

for i in {0..9}; do echo "数字: $i" done

10から1ずつ減らすループ

for i in {10..1}; do echo "カウントダウン: $i" done

C言語風のループ

for ((i=0; i<10; i++)); do echo "C風ループ: $i" done

実務例:ファイル処理

#!/bin/bash

/var/logディレクトリのすべての.logファイルを圧縮

LOG_DIR="/var/log" for LOG_FILE in "$LOG_DIR"/*.log; do if [ -f "$LOG_FILE" ]; then echo "圧縮中: $LOG_FILE" gzip "$LOG_FILE" fi done

2. whileループ

whileループは条件が真の間、処理を繰り返します。

基本構文

while [ 条件 ]; do
    # 処理
done

実践例:ユーザー入力待ち

#!/bin/bash

while true; do
    read -p "続行しますか? (y/n): " ANSWER
    case $ANSWER in
        [yY]|[yY][eE][sS])
            echo "続行します"
            break
            ;;
        [nN]|[nN][oO])
            echo "終了します"
            exit 0
            ;;
        *)
            echo "yまたはnで答えてください"
            ;;
    esac
done

実務例:ログ監視

#!/bin/bash

LOG_FILE="/var/log/syslog"
LAST_SIZE=$(stat -c%s "$LOG_FILE")

while true; do
    CURRENT_SIZE=$(stat -c%s "$LOG_FILE")

    if [ $CURRENT_SIZE -gt $LAST_SIZE ]; then
        echo "ログファイルが更新されました"
        tail -n 10 "$LOG_FILE"
        LAST_SIZE=$CURRENT_SIZE
    fi

    sleep 5
done

3. untilループ

untilループは条件が偽の間、処理を繰り返します。whileループの条件を反転させたものです。

基本構文

until [ 条件 ]; do
    # 処理
done

実践例:サービスの起動確認

#!/bin/bash

SERVICE="nginx"
TIMEOUT=30
INTERVAL=2

echo "サービス $SERVICE の起動を確認中..."

until systemctl is-active --quiet "$SERVICE" || [ $TIMEOUT -le 0 ]; do
    sleep $INTERVAL
    TIMEOUT=$((TIMEOUT - INTERVAL))
    echo "残り時間: $TIMEOUT秒"
done

if systemctl is-active --quiet "$SERVICE"; then
    echo "サービス $SERVICE は正常に起動しました"
else
    echo "エラー: サービス $SERVICE を起動できませんでした"
    exit 1
fi

4. ループ制御

ループ処理を制御するためのキーワードが2つあります。

キーワード説明使用例
breakループを直ちに終了するif [ $i -eq 5 ]; then break; fi
continue現在のイテレーションを終了し、次のイテレーションに進むif [ $i -eq 3 ]; then continue; fi

実践例:

#!/bin/bash

for i in {1..10}; do
    if [ $i -eq 3 ]; then
        echo "3をスキップします"
        continue
    fi

    if [ $i -eq 8 ]; then
        echo "ループを終了します"
        break
    fi

    echo "現在の値: $i"
done

5. ループ処理のベストプ…

  1. ループ回数を最小化する:不要なループは処理時間の無駄
  2. ループ内で重い処理を避ける:可能な限りループ外で処理する
  3. エラー処理を実装する:ループ内でエラーが発生した場合の対処方法を考える
  4. 変数名を分かりやすくする:i, jなどの単純な変数名よりも具体的な名前を使用
  5. ループの終了条件を明確にする:無限ループにならないように注意

関数の定義と呼び出し方

関数は一連の処理をまとめて再利用可能な形で定義する機能です。Bashスクリプトの保守性と再利用性を高めるために不可欠です。

1. 関数の基本構文

Bashにおける関数の定義方法は2種類あります。

方法1:function

この記事で学んだスキルをさらに深めたい方へ

Linuxの知識をさらに深めたい方はこちらの技術書がおすすめです。コマンドラインからサーバー管理まで網羅しています。

Amazonアソシエイトプログラムを利用しています。

ABOUT ME
たから
サラリーマンをしながら開業して経営やってます。 今年、本業で独立・別事業を起業予定です。 ◆経験:IT講師/インフラエンジニア/PM/マネジメント/採用/運用・保守・構築・設計 ◆取得資格:CCNA/CCNP/LPIC-1/AZ-900/FE/サーティファイC言語 ◆サイドビジネス:アパレル事業/複数のWEBメディアを運営