基礎LESSON 08
この教材で学ぶこと command、quote、pipeline、exit statusから安全な自動化を始めます。Bash入門
対象読者: ターミナルで基本操作を行い、短い自動化を安全に書きたい人。
この教材でできるようになること
- command、argument、exit status、pipelineを説明できる
- quoteと変数展開を安全に扱える
- 条件分岐・繰り返し・関数を使える
- 削除や上書きの対象を実行前に確認できる
1. Bashはshellでありprogramming languageでもある
Bashはコマンドを対話的に実行できるだけでなく、変数、条件分岐、関数を使って処理を自動化できます。
printf '%s\n' "Hello"
printf 'exit=%s\n' "$?"
commandは終了時にstatus codeを返します。慣例として0は成功、0以外は失敗です。
2. quoteを習慣にする
file_name='my notes.txt'
printf '%s\n' "$file_name"
変数展開をquoteしないと、空白で単語分割されたりwildcardが展開されたりします。特別な理由がなければ"$variable"と書きます。
3. pipelineとredirection
printf '%s\n' apple banana apricot | rg '^a'
printf '%s\n' "学習記録" > notes.txt
printf '%s\n' "Bash" >> notes.txt
|: 左の標準出力を右の標準入力へ渡す>: ファイルを上書きする>>: ファイル末尾へ追加する2>: 標準エラーをredirectする
上書きは練習用ファイルで確認してから使います。
4. 最小のscript
#!/usr/bin/env bash
set -u
name="${1:-}"
if [[ -z "$name" ]]; then
printf '%s\n' 'Usage: hello.sh NAME' >&2
exit 2
fi
printf 'Hello, %s\n' "$name"
実行します。
chmod +x hello.sh
./hello.sh Kryik
set -eには文脈による例外があるため、魔法の安全装置とは考えません。終了statusをどこで扱うかを設計したうえでset -euo pipefailを選びます。
5. loopと配列
files=(README.md notes.txt)
for file in "${files[@]}"; do
if [[ -f "$file" ]]; then
printf 'found: %s\n' "$file"
else
printf 'missing: %s\n' "$file" >&2
fi
done
配列全体も"${files[@]}"とquoteし、各要素の境界を保ちます。
6. destructive commandの前に対象を固定する
target_dir="./build-output"
if [[ "$target_dir" != "./build-output" || ! -d "$target_dir" ]]; then
printf '%s\n' 'unexpected target' >&2
exit 1
fi
find "$target_dir" -maxdepth 1 -type f -print
対象を表示して確認し、空の変数、root、home directory、予期しないsymlinkを削除対象にしないよう検証します。
演習: 拡張子別に数える
引数でdirectoryを受け取り、その直下にある.mdと.txtの件数を表示するscriptを作ってください。
要件:
- 引数がない、またはdirectoryでない場合はstatus 2
- pathは必ずquoteする
- subdirectoryは数えない
- ファイル名に空白があっても動く
理解チェック
- 標準出力と標準エラーを区別できる
- exit statusを条件分岐に利用できる
- 変数と配列を安全にquoteできる
- 上書き・削除前に対象を検証できる
公式資料
次に読む
Bashシェルスクリプト実践で、エラー処理や運用自動化へ進みます。