実践スクリプト作成
実践スクリプト作成 とは
学んだ知識を応用して、簡単な自動処理を行うシェルスクリプトを作成してみましょう。本レッスンでは、実践スクリプト作成 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
なぜ重要か
ここまでに学んだ変数・引数・if・ループ・関数を組み合わせると、実務で「ありがちな自動化」のほとんどが書けるようになります。仕上げのレッスンでは、入門としていちばん使う型である「引数チェック」と「ファイル数の集計」に絞って、安全で読みやすいスクリプトの書き方を身につけます。題材は、引数で渡したディレクトリ配下のファイル数を数えるスクリプトです。難しい応用テクニックは最後の発展欄でさわりだけ紹介します。
設計の準備
良いシェルスクリプトの共通点は次のとおりです。
- 冒頭に
set -euo pipefailを入れて事故を早期検知する - 引数の数や形式を最初にチェックして使い方を表示する
- 共通処理は関数に切り出して main から呼ぶ
- 終了時の状態 (成功 / 失敗) を
exit 0/exit 1で明示する - 失敗時のメッセージは標準エラー (
>&2) に流す
set -euo pipefail は「未定義変数やコマンド失敗を見つけたらすぐ止まる」ためのおまじないです。最初は意味を丸暗記でかまいません。引数チェックとファイル集計という 2 つの部品さえ書ければ、入門段階のスクリプトとしては十分です。
スクリプトのスケルトン
まずは引数チェックの土台を作ります。引数が無ければ使い方 (usage) を表示して終了し、指定されたディレクトリが存在しない場合もエラーにします。
ターミナル
#!/bin/bash
set -euo pipefail
usage() {
echo "usage: $0 <directory>" >&2
}
main() {
if [[ $# -lt 1 ]]; then
usage
exit 1
fi
local dir=$1
if [[ ! -d "$dir" ]]; then
echo "directory not found: $dir" >&2
exit 1
fi
echo "target: $dir"
}
main "$@"ここまでで「引数チェック」「ディレクトリ存在チェック」の土台が揃いました。実務でも、まずこの形を書いてから本処理を書き足す、という進め方が安全です。
全体の流れ
ファイル数集計の実装
本処理として、ディレクトリ配下のファイル数を数える関数を追加します。find でファイル一覧を取得し、wc -l で行数 (= ファイル数) を数えるのが定石です。
ターミナル
#!/bin/bash
set -euo pipefail
usage() {
echo "usage: $0 <directory>" >&2
}
count_files() {
local dir=$1
find "$dir" -type f | wc -l | tr -d ' '
}
main() {
if [[ $# -lt 1 ]]; then
usage
exit 1
fi
local dir=$1
if [[ ! -d "$dir" ]]; then
echo "directory not found: $dir" >&2
exit 1
fi
echo "files: $(count_files "$dir")"
}
main "$@"count_files は引数で受け取ったディレクトリのファイル数を返す関数です。tr -d ' ' は wc が付ける余分な空白を削り、files: 3 のようにきれいな数字だけを出力するための処理です。引数チェックと集計関数、この 2 つが組み合わさったものが「実務で通用するスクリプトの最小形」です。
よくある間違い
$1をクオートせずfind $dirと書くと、空白を含むパスで壊れます。必ず"$dir"と書きます。- 引数チェックを忘れると、引数なしで実行したときに意味不明なエラーが出ます。先頭で
$#を確認しましょう。 set -euo pipefailを入れたまま、失敗してもよいコマンドをそのまま書くと途中で止まります。続けたい箇所は後述の発展欄を参照してください。
やってみよう
手元のディレクトリを 1 つ用意し、上のスクリプトを count.sh として保存して bash count.sh ディレクトリ名 を実行してみましょう。空のディレクトリ、ファイルが数個あるディレクトリの両方で試し、files: の数が正しく変わることを確認します。
発展
入門段階では引数チェックと集計までで十分ですが、運用スクリプトでは次のテクニックもよく使われます。今は名前と用途だけ覚えておけば十分です。
- プロセス置換
< <(find ...)は、findの結果を while ループに渡しても変数がループ後に消えない書き方です。 tee -a ファイル名は、画面に表示しつつ同じ内容をログファイルにも追記するコマンドで、cron 実行スクリプトの定番です。trap clean_up EXITは、スクリプト終了時に一時ファイル削除などの後片付けを自動実行する仕掛けです。bash -x script.shでトレース実行すると、1 行ずつどんな展開で動いたかが見え、原因不明のバグ調査に役立ちます。
まとめ
- 冒頭に
set -euo pipefailを入れて事故を防ぐ - usage 関数で使い方を表示し、必須引数とディレクトリの存在を検証する
find+wc -lでファイル数を数えるのは定石tr -d ' 'で出力をきれいな数字だけにする- 引数チェックと集計関数の組み合わせが、実務で通用するスクリプトの最小形
trap/tee/ プロセス置換 /bash -xは運用で役立つ発展テクニック
次のレッスン
次は シェルスクリプトチェック で、学んだ知識を応用して、簡単な自動処理を行うシェルスクリプトを作成してみましょう を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 実践スクリプト の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 実践スクリプト とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
課題
- ファイル数を数える関数を定義する
- 0/2/3 ファイルのディレクトリを用意する
- find と wc -l で各ディレクトリのファイル数を出力する