シェルスクリプト

総合練習問題

小さなログ集計とバックアップを完成させ、学んだ構文を組み合わせます。

シェルスクリプト入門の講座一覧

01

練習データを準備する

次のコマンドを、~/shellscript-practiceの中で実行します。

データ作成COMMAND
mkdir -p project/logs project/backup
printf 'INFO start\nERROR timeout\nINFO retry\nERROR failed\n' > project/logs/app.log
printf 'source code\n' > project/main.txt
printf 'config\n' > project/settings.conf
find project -type f -print | sort
表示例OUTPUT
project/logs/app.log
project/main.txt
project/settings.conf
02

問題1:ERRORの件数を集計する

project/logs/app.logからERRORを含む行だけを表示し、件数をERROR件数: 2の形式で出力してください。

ヒント grepの結果をwc -lへ渡します。検索結果がない場合の終了ステータスも考えてみましょう。
解答例を表示
解答BASH
log='project/logs/app.log'
error_lines=$(grep 'ERROR' "$log" || true)
printf '%s\n' "$error_lines"
error_count=$(printf '%s\n' "$error_lines" | grep -c 'ERROR' || true)
printf 'ERROR件数: %s\n' "$error_count"
実行結果OUTPUT
ERROR timeout
ERROR failed
ERROR件数: 2
03

問題2:ファイルをバックアップする

project/main.txtとproject/settings.confをproject/backup/へコピーしてください。保存先がなければ作成します。

ヒント mkdir -p、cp、[[ -f ... ]]を使います。対象がない場合はエラーにします。
解答例を表示
解答BASH
source_dir='project'
backup_dir="$source_dir/backup"
mkdir -p "$backup_dir"

for file in "$source_dir/main.txt" "$source_dir/settings.conf"; do
    if [[ ! -f "$file" ]]; then
        printf 'ありません: %s\n' "$file" >&2
        exit 1
    fi
    cp "$file" "$backup_dir/"
done
find "$backup_dir" -type f -print | sort
実行結果OUTPUT
project/backup/main.txt
project/backup/settings.conf
04

問題3:関数へ分ける

問題1と問題2の処理を、count_errorsとbackup_fileという関数へ分けてください。関数は引数を受け取り、失敗時に0以外を返します。

ヒント 関数内の一時変数へlocalを付け、ファイルがなければreturn 1を使います。
05

総合解答:ログ確認とバックアップ

次のスクリプトは、入力ディレクトリを確認し、ログのERROR件数を表示して、設定ファイルをバックアップします。

review.shBASH
#!/usr/bin/env bash
set -u

count_errors() {
    local log_file="$1"
    if [[ ! -f "$log_file" ]]; then
        printf 'ログがありません: %s\n' "$log_file" >&2
        return 1
    fi
    grep -c 'ERROR' "$log_file" || true
}

backup_file() {
    local source="$1"
    local destination="$2"
    if [[ ! -f "$source" ]]; then
        printf 'ファイルがありません: %s\n' "$source" >&2
        return 1
    fi
    mkdir -p "$(dirname "$destination")"
    cp "$source" "$destination"
}

project_dir="${1:-project}"
log_file="$project_dir/logs/app.log"
backup_file_path="$project_dir/backup/settings.conf"

if [[ ! -d "$project_dir" ]]; then
    printf 'プロジェクトがありません: %s\n' "$project_dir" >&2
    exit 2
fi

printf 'ERROR件数: %s\n' "$(count_errors "$log_file")"
backup_file "$project_dir/settings.conf" "$backup_file_path"
printf 'バックアップ完了: %s\n' "$backup_file_path"
実行例COMMAND / OUTPUT
bash review.sh project
ERROR件数: 2
バックアップ完了: project/backup/settings.conf

この解答をそのまま本番で使うのではなく、空のログ、存在しない設定ファイル、空白を含むパス、権限エラーを試してから自分の用途へ変更します。

06

次に学ぶこと

シェルスクリプトの基礎を終えたら、実際の作業へ小さく適用します。cronやsystemd timerによる定期実行、ログローテーション、SSH、デプロイ、CIなどが次のテーマです。