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

Bashスクリプト基礎入門|変数・条件分岐・ループを完全マスター
Linux/Unix環境で自動化を実現するならBashスクリプトが最適です。変数宣言・条件分岐・ループ処理を正しく使いこなせば、日々の運用作業を数分で完了させられます。本記事では実務で即座に活用できる具体的な書き方を、実行可能なサンプルコードと共に解説します。初心者でも1日で基本構文を習得できる内容です。
目次
- Bashスクリプトとは何か
- 実行環境の準備と基本設定
- 変数の宣言と活用方法
- 条件分岐(if文・case文)の完全ガイド
- ループ処理(for・while・until)の実践テクニック
- 関数の定義と呼び出し方
- エラー処理とデバッグ手法
- 実務で使えるベストプラクティス
- Bashスクリプトに関するよくある質問
- まとめ:次に学ぶべきこと
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 |
| $$ | 現在のプロセスID | echo "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. ループ処理のベストプ…
- ループ回数を最小化する:不要なループは処理時間の無駄
- ループ内で重い処理を避ける:可能な限りループ外で処理する
- エラー処理を実装する:ループ内でエラーが発生した場合の対処方法を考える
- 変数名を分かりやすくする:i, jなどの単純な変数名よりも具体的な名前を使用
- ループの終了条件を明確にする:無限ループにならないように注意
関数の定義と呼び出し方
関数は一連の処理をまとめて再利用可能な形で定義する機能です。Bashスクリプトの保守性と再利用性を高めるために不可欠です。
1. 関数の基本構文
Bashにおける関数の定義方法は2種類あります。
方法1:function
この記事で学んだスキルをさらに深めたい方へ
Linuxの知識をさらに深めたい方はこちらの技術書がおすすめです。コマンドラインからサーバー管理まで網羅しています。
Amazonアソシエイトプログラムを利用しています。
この記事で学んだスキルをさらに深めたい方へ
Linuxの知識をさらに深めたい方はこちらの技術書がおすすめです。コマンドラインからサーバー管理まで網羅しています。
Amazonアソシエイトプログラムを利用しています。




