変更要約: 初版(主題1.06・副主題1.06.1〜1.06.2に対応)
1.2シェルスクリプト
102試験で最重要(重要度6)のシェルスクリプトを学びます。シバン(#!)、実行権の管理(chmod・chown)、位置パラメータ($0・$1..$n・$#・$*・$@・shift)、終了ステータス($?・exit)、条件分岐(if・case)、ループ(for・while)、シェル関数、PATH に依存しない書き方、デバッグ(bash -x・bash -v)を押さえます。
定型作業を自動化するシェルスクリプトは、102試験の全副主題で最大の重要度6が割り当てられた本丸です。「Linux スキルの無いユーザーにも安全に実行させられる部品を作る」のがゴールで、構文の暗記ではなく引数・戻り値・分岐の振る舞いが問われます。
1.2.1スクリプトの骨格
- 先頭行のシバン(
#!/bin/bash)=このスクリプトを解釈するインタプリタを指定。sh・python 等も同じ仕組み。 - 実行の条件=読み取り権+実行権(
chmod +x script.sh→./script.sh)。所有権は chown で管理。実行権が無くてもbash script.shなら動く(読み取り権のみで可)。 - 位置パラメータ=
$0(スクリプト名)・$1〜$n(n 番目の引数)・$#(引数の個数)・$*/$@(全引数)。shift は引数を1つ左へずらす($2 が $1 に)。 - 終了ステータス=直前のコマンドの成否を $? で参照(0=成功・0以外=失敗)。スクリプト自身の戻り値は exit N で指定。
1.2.2分岐・ループ・関数
- if=
if [ "$1" = "start" ]; then …; elif …; else …; fi([ ]は test コマンド。終わりは fi)。 - case=1つの値をパターンで多分岐(
case "$1" in start) …;; stop) …;; *) …;; esac。終わりは esac・既定は*))。 - for=リストを順に処理(
for f in *.log; do …; done)/while=条件が真の間繰り返す(while read line; do …; done < file)。終わりはどちらも done。 - シェル関数=よく使う一連の処理に名前を付ける(
backup() { tar czf "$1.tar.gz" "$1"; })。function キーワードでも定義可。関数内の$1は関数の引数を指す。 - PATH に依存しないスクリプト=コマンドを絶対パスで書く/必要な PATH をスクリプト冒頭で自ら設定する(利用者の環境差で壊れない部品にする)。デバッグ=bash -x(実行したコマンドを展開表示)・bash -v(読み込んだ行をそのまま表示)。
「$#=引数の個数・$0=スクリプト名・$?=直前の終了ステータス(0=成功)」 の3点は即答できるように。「if→fi・case→esac・for/while→done」の対応、「実行トレース=bash -x」、「shift で $1 を消費しながらループ処理」 も定番です。「exit 1 は成功を意味する」型の誤答(0が成功)に注意。
30行の実用スクリプトを頭の中で組み立ててみましょう。サービス操作ラッパー svc.sh start nginx を書くなら:先頭に シバン、次に if [ $# -ne 2 ]; then echo "Usage: $0 {start|stop} name"; exit 1; fi で引数チェック(个数が違えば使い方を出して失敗終了)。続いて case "$1" in start|stop) systemctl "$1" "$2";; *) exit 2;; esac で許可した操作だけ通します。呼び出し元は svc.sh start nginx && echo OK || echo NG のように $? を(&&/|| 経由で)見て後続を決められます——「戻り値 0=成功」の約束を守ることが、部品として使えるスクリプトの条件です。複数ファイルを処理するなら for f in "$@"; do process "$f"; done、引数を先頭から食べていくなら while [ $# -gt 0 ]; do …; shift; done が定型です。動かないときは bash -x svc.sh start nginx で変数が何に展開されたかを1行ずつ確認するのが最短の近道です。
| 変数/構文 | 意味 | 対 |
|---|---|---|
| $0 / $1..$n / $# / $@ | 名前/n番目/個数/全引数 | shift で左詰め |
| $? / exit N | 直前の結果/自身の戻り値 | 0=成功・非0=失敗 |
| if / case | 条件分岐/パターン多分岐 | fi / esac で閉じる |
| for / while | リスト反復/条件反復 | done で閉じる |
ひっかけ: 「$# はスクリプト名を含む引数の総数」は誤りです。$# は引数のみの個数(スクリプト名 $0 は含まない)。また「終了ステータスは 1 が成功」も誤り=0 が成功で、0以外は失敗(エラー種別を表す任意の値)です。「case の終わりは endcase」「if の終わりは endif」のような閉じ語の捏造も定番の誤答です(正しくは esac・fi)。
1.2.3この節のまとめ
- 骨格=#!シバン+chmod +x。引数は $0/$1../$#/$@・shift、成否は $?(0=成功)・exit N
- 分岐 if…fi/case…esac・反復 for/while…done・部品化は関数。デバッグは bash -x(トレース)
進捗の記録にはログインが必要です。
理解度チェック
(軽い確認用)Q1. スクリプトに渡された「引数の個数」を参照して、不足時に使い方を表示して終了したい。個数を保持している特殊変数はどれ?
Q2. 直前に実行したコマンドが成功したかどうかをスクリプト内で判定したい。参照すべき値と成功の条件は?
Q3. スクリプトが期待どおり動かないため、実行された各コマンドが変数展開後の形で順に表示されるようにして原因を調べたい。適切な実行方法は?

