基礎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シェルスクリプト実践で、エラー処理や運用自動化へ進みます。