コース一覧
LinuC レベル1 102試験対策(LPIC-1対応)
スクリプトの制御

LinuC レベル1 102試験対策(LPIC-1対応)

LinuC レベル1/LPIC-1の102範囲を、シェル、ユーザーとセキュリティ、ネットワーク、システム管理の実機演習と章末問題で固めます。Linuxを安全に運用するための知識とコマンド操作を体系的に身につける25レッスンのコースです。

1
102 シェルとスクリプト
01. シェル環境18分
02. testと条件式18分
03. スクリプトの制御18分
04. cronとat15分
05. systemdタイマー18分
06. 過去問 シェル15分
2
102 ユーザーとセキュリティ
01. passwdとshadow18分
02. ユーザー管理コマンド18分
03. suとsudo18分
04. 特殊パーミッション18分
05. ホストのセキュリティ18分
06. SSHとGPG18分
07. 過去問 ユーザーとセキュリティ15分
3
102 ネットワーク
01. TCP/IPとウェルノウンポート18分
02. アドレス設定18分
03. ルーティング18分
04. 名前解決の設定18分
05. 疎通トラブルシュート18分
06. 過去問 ネットワーク15分
4
102 システム管理
01. 時刻とNTP15分
02. ロケールと文字コード18分
03. ログ管理18分
04. サービス管理の試験形式18分
05. メールと印刷のきほん15分
06. 過去問 システム管理15分

スクリプトの制御

出題は「このスクリプトを実行すると何が出力されるか」という形で来ます。書けるだけでは足りず、読めないと当たりません。似た言語の記憶で書くと必ず外すので、シェル独自の形として覚え直します。

なお、1行目の #! から始まる行をシバンと呼び、どのインタプリタで実行するかを指定します。効くのは実行権限を付けて ./script.sh と直接起動したときだけで、bash script.sh のようにインタプリタを明示した場合はただのコメントとして無視されます。

for は3つの書き方がある

リスト形式が基本です。空白で区切られた要素を左から順に取り出します。

ターミナル

for fruit in apple banana cherry; do
  echo "$fruit"
done

数値の並びは、外部コマンドの seq か bash のブレース展開で作ります。

ターミナル

for n in $(seq 1 3); do echo "$n"; done
for n in {1..3}; do echo "$n"; done
for n in {0..10..2}; do echo "$n"; done   # 2 ずつ。bash 4 以降

ブレース展開はシェルの機能なので外部コマンドを呼びませんが、{1..$N} のように変数を書くと展開されません。変数で回数を決めるなら seq か C 言語形式を使います。

ターミナル

for ((n = 0; n < 3; n++)); do
  echo "$n"
done

初期化と継続条件と更新をセミコロンで区切ります。この形は bash の拡張で sh では動きません。for arg in "$@" と書けば、スクリプトに渡された引数を順に処理できます。

while と until は条件が裏返し

while は条件が真である間、until は条件が真になるまで繰り返します。条件を反転させれば同じ動きになります。

ターミナル

n=1
while [ "$n" -le 3 ]; do
  echo "$n"
  n=$((n + 1))
done

$((...)) は算術展開で、中では変数に $ を付けなくても構いません。ファイルを1行ずつ処理する while read も定番です。

ターミナル

while read line; do
  echo "[$line]"
done < /etc/hostname

read は標準入力から1行読んで変数に入れ、入力が尽きると 0 以外を返すのでループが止まります。break はループを抜け、continue は残りをとばして次の繰り返しへ進みます。break 2 のように数字を付けると、その数だけ外側のループまで抜けます。

case の閉じは esac、分岐の終わりは ;;

ターミナル

case "$mode" in
  start)
    echo starting
    ;;
  stop|halt)
    echo stopping
    ;;
  *)
    echo usage
    ;;
esac

パターンの後ろは閉じ括弧だけで、開き括弧は要りません。各分岐の終わりは ;; で、セミコロン1つでは足りません。複数のパターンは縦棒で並べます。*) は何にも一致しなかったときの既定の分岐で、最後に置きます。全体を閉じるのは esac です。

パターンにはワイルドカードが使えます。C 言語の switch と違い、一致した分岐を実行したらそこで case を抜けるので break は不要です。

引数は特殊変数で受け取る

変数意味
$0スクリプト自身の名前
$1 $2 …1番目、2番目の引数。10 番目以降は ${10}
$#引数の個数。$0 は数に入らない
$@全引数。"$@" は1つずつ別の語として展開される
$*全引数。"$*" は全部つないで1つの語になる
$?直前のコマンドの終了ステータス。0 が成功
$$実行中のシェルのプロセス ID

shift は位置パラメータを1つ前へずらします。$2 が $1 になり、$# が1減ります。exit はスクリプトを終了し、exit 0 が成功、それ以外が失敗の合図です。

試験で狙われるところ

case の閉じは esac、if は fi、ループは done です。case の各分岐は ;; で終えます。C 言語形式の for ((...)) は bash 拡張で #!/bin/sh では動きません。$# に $0 は含まれません。そして "$@" と "$*" は展開のされ方が違います。

ヒント

ヒアドキュメントは cat <<'EOF' > /root/grade.sh で始め、最後に EOF だけの行を書いて閉じます。EOF をシングルクォートで囲むと $1 や $sum がそのまま書き込まれます

case のパターンは 90) のように閉じ括弧だけを書きます。各分岐の終わりは ;; の2つ、全体の閉じは esac です

足し算は算術展開 $((sum + i)) です。for i in 1 2 3 4 5 でも for i in {1..5} でも構いません

  • 1. cat <<'EOF' > /root/grade.sh の形でスクリプトを書き出す
  • 2. 1行目にシバン #!/bin/bash を書く
  • 3. case "$1" in 90) echo A ;; 70) echo B ;; *) echo C ;; esac で評語を判定する
  • 4. sum=0 としてから for i in 1 2 3 4 5 で回し、sum=$((sum + i)) で足していく
  • 5. echo "SUM $sum" で合計を表示する
  • 6. chmod +x /root/grade.sh で実行権限を付ける
  • 7. bash /root/grade.sh 90 などを実行して出力を確かめる

Linux は使うときに起動します(初回は約102MB通信します)

6 項目で採点します