練習データを準備する
次のコマンドを、~/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問題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問題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問題3:関数へ分ける
問題1と問題2の処理を、count_errorsとbackup_fileという関数へ分けてください。関数は引数を受け取り、失敗時に0以外を返します。
ヒント 関数内の一時変数へ
localを付け、ファイルがなければreturn 1を使います。総合解答:ログ確認とバックアップ
次のスクリプトは、入力ディレクトリを確認し、ログの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この解答をそのまま本番で使うのではなく、空のログ、存在しない設定ファイル、空白を含むパス、権限エラーを試してから自分の用途へ変更します。
次に学ぶこと
シェルスクリプトの基礎を終えたら、実際の作業へ小さく適用します。cronやsystemd timerによる定期実行、ログローテーション、SSH、デプロイ、CIなどが次のテーマです。