シェルスクリプトとは

シェルスクリプトは、コマンドを連続して実行するプログラムです。手作業で繰り返す操作を自動化できます。

シェルスクリプトのメリット

  • ✅ 繰り返し作業の自動化
  • ✅ 複雑なコマンドを簡単に実行
  • ✅ エラーを減らせる
  • ✅ 処理の再現性が高い
  • ✅ チームでの共有が容易

基本的なスクリプトの作成

Hello Worldスクリプト

#!/bin/bash
# これはコメントです

echo "Hello, World!"

重要な要素

  • #!/bin/bash: シェバン(shebang) - どのシェルで実行するか指定
  • echo: 文字列を出力するコマンド
  • #: コメント(実行されない)

スクリプトの作成と実行

# スクリプトファイルを作成
nano hello.sh

# 実行権限を付与
chmod +x hello.sh

# 実行
./hello.sh

変数の使い方

変数の定義と使用

#!/bin/bash

# 変数の定義(=の前後にスペースを入れない)
name="太郎"
age=25

# 変数の使用($を付ける)
echo "名前: $name"
echo "年齢: $age歳"

# 波括弧で明示的に指定
echo "名前は${name}です"

コマンドの結果を変数に格納

#!/bin/bash

# $()でコマンドの結果を変数に代入
current_date=$(date +%Y-%m-%d)
file_count=$(ls -1 | wc -l)

echo "今日は: $current_date"
echo "ファイル数: $file_count個"

条件分岐(if文)

基本的なif文

#!/bin/bash

age=20

if [ $age -ge 20 ]; then
    echo "成人です"
else
    echo "未成年です"
fi

比較演算子

  • -eq: 等しい(equal)
  • -ne: 等しくない(not equal)
  • -gt: より大きい(greater than)
  • -ge: 以上(greater or equal)
  • -lt: より小さい(less than)
  • -le: 以下(less or equal)

文字列の比較

#!/bin/bash

str="hello"

if [ "$str" = "hello" ]; then
    echo "一致しました"
fi

# 空文字チェック
if [ -z "$str" ]; then
    echo "空です"
else
    echo "空ではありません"
fi

ファイルの存在確認

#!/bin/bash

if [ -f "test.txt" ]; then
    echo "test.txtは存在します"
else
    echo "test.txtは存在しません"
fi

ファイル・ディレクトリのテスト演算子

  • -f: ファイルが存在する
  • -d: ディレクトリが存在する
  • -r: 読み取り可能
  • -w: 書き込み可能
  • -x: 実行可能

ループ処理

forループ

#!/bin/bash

# 連番のループ
for i in 1 2 3 4 5
do
    echo "数値: $i"
done

# {開始..終了}の形式
for i in {1..5}
do
    echo "番号: $i"
done

# ファイルのループ
for file in *.txt
do
    echo "ファイル: $file"
done

whileループ

#!/bin/bash

count=1

while [ $count -le 5 ]
do
    echo "カウント: $count"
    count=$((count + 1))
done

関数の定義

#!/bin/bash

# 関数の定義
greet() {
    echo "こんにちは、$1さん!"
}

# 関数の呼び出し
greet "太郎"
greet "花子"

# 戻り値を持つ関数
add() {
    result=$(($1 + $2))
    echo $result
}

sum=$(add 10 20)
echo "合計: $sum"

実用的なスクリプト例

例1: バックアップスクリプト

#!/bin/bash

# バックアップ設定
SOURCE_DIR="/home/user/documents"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="backup_${DATE}.tar.gz"

# バックアップ実行
echo "バックアップを開始します..."
tar -czf "${BACKUP_DIR}/${BACKUP_FILE}" "$SOURCE_DIR"

if [ $? -eq 0 ]; then
    echo "バックアップ成功: ${BACKUP_FILE}"
else
    echo "バックアップ失敗"
    exit 1
fi

# 7日以上前のバックアップを削除
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +7 -delete
echo "古いバックアップを削除しました"

例2: ログ監視スクリプト

#!/bin/bash

LOG_FILE="/var/log/app.log"
KEYWORD="ERROR"

# ログファイルの監視
tail -n 0 -f "$LOG_FILE" | while read line
do
    if echo "$line" | grep -q "$KEYWORD"; then
        echo "[ALERT] エラー検出: $line"
        # メール通知やSlack通知などを追加可能
    fi
done

例3: システム情報レポート

#!/bin/bash

REPORT_FILE="system_report_$(date +%Y%m%d).txt"

echo "=== システムレポート ===" > "$REPORT_FILE"
echo "作成日時: $(date)" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"

echo "--- ディスク使用量 ---" >> "$REPORT_FILE"
df -h >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"

echo "--- メモリ使用量 ---" >> "$REPORT_FILE"
free -h >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"

echo "--- CPU情報 ---" >> "$REPORT_FILE"
lscpu | grep "Model name" >> "$REPORT_FILE"

echo "レポートを作成しました: $REPORT_FILE"

引数の処理

位置パラメータ

#!/bin/bash

echo "スクリプト名: $0"
echo "第1引数: $1"
echo "第2引数: $2"
echo "全引数: $@"
echo "引数の数: $#"

実行例:

./script.sh apple banana
# 出力:
# スクリプト名: ./script.sh
# 第1引数: apple
# 第2引数: banana
# 全引数: apple banana
# 引数の数: 2

オプション解析

#!/bin/bash

while getopts "f:v" opt; do
    case $opt in
        f)
            filename="$OPTARG"
            echo "ファイル: $filename"
            ;;
        v)
            verbose=true
            echo "詳細モード有効"
            ;;
        \?)
            echo "無効なオプション: -$OPTARG"
            exit 1
            ;;
    esac
done

エラーハンドリング

終了ステータスの確認

#!/bin/bash

# コマンド実行
cp source.txt dest.txt

# 直前のコマンドの終了ステータス
if [ $? -eq 0 ]; then
    echo "コピー成功"
else
    echo "コピー失敗"
    exit 1
fi

set -e でエラー時に即終了

#!/bin/bash

# エラーが発生したら即座に終了
set -e

echo "処理開始"
cd /nonexistent/directory  # ここでエラーが発生し終了
echo "この行は実行されない"

エラートラップ

#!/bin/bash

cleanup() {
    echo "クリーンアップ処理実行"
    rm -f temp_file.txt
}

# エラー時にcleanup関数を実行
trap cleanup EXIT ERR

echo "処理開始"
# 何か処理
echo "処理完了"

デバッグ技法

デバッグモード

#!/bin/bash

# -x オプションで実行内容を表示
set -x

name="太郎"
echo "Hello, $name"

# デバッグモード解除
set +x

実行時デバッグ

# コマンドラインからデバッグ実行
bash -x script.sh

ベストプラクティス

1. シェバンは必ず記述

#!/bin/bash

2. 変数は引用符で囲む

# 良い例
if [ "$var" = "value" ]; then

# 悪い例(変数が空の場合エラー)
if [ $var = "value" ]; then

3. エラーチェックを徹底

set -euo pipefail
# -e: エラーで終了
# -u: 未定義変数でエラー
# -o pipefail: パイプ中のエラーを検出

4. コメントを適切に書く

# 何をするスクリプトか
# 引数は何か
# 前提条件は何か

便利なワンライナー集

# ファイルの一括リネーム
for f in *.txt; do mv "$f" "${f%.txt}.bak"; done

# 特定の拡張子ファイルを検索して削除
find . -name "*.log" -type f -delete

# ディレクトリサイズのトップ10
du -sh * | sort -rh | head -10

# プロセスのメモリ使用量トップ10
ps aux | sort -rk 4 | head -10

まとめ

シェルスクリプトは日常的な作業を劇的に効率化できる強力なツールです。

学んだこと

  • 変数、条件分岐、ループの基本構文
  • 関数の定義と使用
  • 実用的なスクリプト例
  • エラーハンドリングとデバッグ
  • ベストプラクティス

次のステップ

  • sedやawkでテキスト処理
  • cronで定期実行
  • systemdでサービス化
  • より高度な制御構造