修了演習 ── check-logins スクリプトを完成させる
あなたの手で書く 2 行のシェルスクリプトが、Linux 学習の最小単位を 1 周回します。chmod・PATH・$()・> ── Part 1 で覚えた道具を全部使って、1 本のレポートを生み出します。
| 所要時間 | 約 75 分(通常章の 1.5 倍 / 11 ステップ) |
|---|---|
| 章タイプ | lab |
| 前提知識 | Chapter 1-7 全部(SSH / ファイル操作 / grep・パイプ / vim / 環境変数 / 権限) |
| 使用機材 | 踏み台 workstation01 + 演習用サーバ learner01 |
| 関連章 | 前: Chapter 7「ユーザとパーミッション」/ 次: Part 2「ネットワーク基礎」 |
Part 1 の知識を 1 本のシナリオで使い切る
Chapter 1 〜 7 の道具を 1 本のシナリオ に組み立てる修了演習です。/var/log/auth.log を読む自作スクリプト check-logins(v1 → v2 の 2 段階)を作って、結果をファイルに保存します。所要 75 分。
$ check-logins > ~/report.txt $ cat ~/report.txt Failed logins on 2026年 5月 17日 日曜日 11:13:47 JST: 4 Successful logins: 7
Chapter 1 〜 7 のどこを使うか(再演マップ)
check-logins はたった 2 行の小さなシェルスクリプトですが、これを作るために Chapter 1 〜 7 で習ったことを 1 つも飛ばさず 通り抜けます。v1 = version 1(最初に書く版)/ v2 = version 2(改修版) の 2 段階で育てます。
| 使う章 | 何を再演するか |
|---|---|
| Ch1 | ssh student@learner01 で接続する |
| Ch2 | cd ~ / ls -la で現状把握 |
| Ch3 | mkdir ~/bin / touch でファイル作成、後半で cp バックアップ → rm の現場の作法 |
| Ch4 | grep "Failed password" /var/log/auth.log | wc -l の集計 |
| Ch5 | vim で v1 を書き、後半で dd / yy / :N を使って v2 に修正 |
| Ch6 | echo $PATH で確認、~/.bashrc に export PATH を追記、source で反映 |
| Ch7 | chmod +x で実行権限を付ける、adm グループで /var/log/auth.log を読む |
スクリプトとは、複数の Linux コマンドを 1 つのファイルにまとめて、まとめて実行できるようにしたもの。中身は vim で書いたただのテキストファイル ── でも #!/bin/bash と chmod +x があれば 自分専用のコマンド として動き出します。新概念は リダイレクト > ひとつだけ(演習中の callout で説明します)。
この章を終えるとできること
自作ツールを動かす 4 動作 を手に覚えます。
スクリプトを書く
どこからでも呼べる
→ rm で不要分を削除
レポートをファイル化
この 4 動作を 1 セッションで通せると、「Permission denied」「command not found」「cannot open auth.log」 という Part 1 で覚えた 3 大エラー に出会っても、原因が即座に切り分けられて、自分で直せます。
試してみよう:check-logins を一から作って、レポートに残す
Chapter 1 〜 7 のすべてを使って、自作スクリプト → PATH 通し → 改修 → レポート化 までを 1 セッションで通します。
演習環境
| 出発地点 | 踏み台 workstation01(alice でログイン中) |
|---|---|
| 接続先 | 演習用サーバ learner01 |
| ログインユーザー | student |
| 前提 | Chapter 1-7 の演習完了(adm は学習環境で student に事前付与済み/その種明かしは Ch7) |
| 所要時間 | 約 75 分(11 ステップ) |
触るのは ~/bin/ 配下のファイルと ~/.bashrc の末尾 1 行、~/report.txt の 3 つだけ。すべて元に戻せる操作です。root 権限は不要(adm は学習環境で事前付与済みの前提)。.bashrc を触るところで > ではなく >> を使うことだけ注意してください(STEP 06 で詳述)。
SSH 接続 ── workstation01 から learner01 へ
ssh student@learner01
Chapter 1 でやった踏み台から演習サーバへのジャンプを再演します。プロンプトが student@learner01:~$ に変わったら入室成功。
現状把握 ── cd ~ / ls -la
cd ~ ls -la # → 合計 32 # → drwxr-x--- 5 student student 4096 5月 17 11:13 . # → drwxr-xr-x 6 root root 4096 5月 12 08:47 .. # → -rw-r--r-- 1 student student 220 3月 31 2024 .bash_logout # → -rw-r--r-- 1 student student 3771 5月 17 11:13 .bashrc # → drwx------ 2 student student 4096 5月 12 08:48 .cache # → drwx------ 3 student student 4096 5月 12 08:48 .local # → -rw-r--r-- 1 student student 807 3月 31 2024 .profile # → drwx------ 2 student student 4096 5月 17 11:09 .ssh
~/bin が見当たらないことを確認(Chapter 2 で習った「ls -la で隠しファイルまで見る」)。
~/bin を作っていればここに bin ディレクトリも表示され、中に hello スクリプトが残っているはずです。それで問題ありません、消す必要はありません。次のステップ ③ の mkdir ~/bin だけは「既に存在します」とエラーになるのでスキップして、touch ~/bin/check-logins から進めてください。作る ── mkdir ~/bin と touch ~/bin/check-logins
mkdir ~/bin # ★ ~/bin が既にある人はこの行をスキップ touch ~/bin/check-logins ls -la ~/bin/ # → 合計 8 # → drwxrwxr-x 2 student student 4096 5月 17 11:13 . # → drwxr-x--- 6 student student 4096 5月 17 11:13 .. # → -rw-rw-r-- 1 student student 0 5月 17 11:13 check-logins
mkdir: ディレクトリを作成できません: ファイルが存在します と出たら: Chapter 6 / Chapter 7 で既に ~/bin を作っているからです。エラーですが 害はありません(既存ディレクトリは壊れません)。そのまま次の touch から進めてください。touch直後の権限は-rw-rw-r--(Ubuntu のumask=002の効果 / Chapter 7 で観察したのと同じ)- まだ
xがない ことに注目してください。これが後でPermission deniedを引き起こします。 - 既存
~/binを使い回した人は、上記の表示にhello(Ch6/Ch7 で作ったもの)も並んでいます。それで OK。
$() コマンド置換 次の STEP 04 で書く v1 の中に $(grep "Failed password" /var/log/auth.log | wc -l) という形が出てきます。これは コマンド置換 という記法で、括弧の中のコマンドを先に実行して、その出力結果を文字列として埋め込む 働きをします。たとえば echo "今日は $(date) です" と書くと、実行時に date が走って「今日は 2026年 5月 17日 ... です」になります。echo の文字列を 動的に組み立てる 道具で、Part 3 以降のシェルスクリプトで毎回登場します。vim で v1 を書く
v1 = version 1(最初に書く版)。失敗ログイン数だけを表示するシンプルな 2 行スクリプトを作ります。
vim ~/bin/check-logins
Chapter 5 で覚えた i で挿入モード → :wq で保存終了 だけで OK。中身:
#!/bin/bash echo "Failed logins: $(grep "Failed password" /var/log/auth.log | wc -l)"
たった 2 行。#!/bin/bash は シバン (shebang) といって、「このファイルは bash で実行してね」とシェルに伝える宣言です。
cat ~/bin/check-logins ls -la ~/bin/check-logins # → -rw-rw-r-- 1 student student 86 5月 17 11:13 /home/student/bin/check-logins
実行 → Permission denied → chmod +x
~/bin/check-logins
# → bash: /home/student/bin/check-logins: 許可がありません
Chapter 7 で習ったとおり、x が付いていないと実行できません。これは Linux 初心者なら誰もが通る関門。落ち着いて chmod +x で実行権限を付け足します。
chmod +x ~/bin/check-logins ls -la ~/bin/check-logins # → -rwxrwxr-x 1 student student 86 5月 17 11:13 /home/student/bin/check-logins ~/bin/check-logins # → Failed logins: 4
x を付けた瞬間に実行できるようになりました。Chapter 7 の「chmod +x で実行ファイルになる」を、今度は自分の手で再演しました。
> / >> / < コマンドの出力は通常 画面(標準出力) に表示されますが、ファイルに流し替える のがリダイレクトです。この後 STEP 06 で >>、STEP 10 で > を使います。
| 演算子 | 意味 |
|---|---|
> | ファイルに 上書き(既存内容は消える) |
>> | ファイルに 追記(既存内容の末尾に追加) |
< | ファイルの中身を 標準入力に流し込む(読み込み専用) |
PATH を通す ── echo $PATH → ~/.bashrc → source
スクリプトを フルパスではなくコマンド名で 呼びたいので、PATH を通します。
echo $PATH # → /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin check-logins # → bash: check-logins: コマンドが見つかりません
~/bin が $PATH に含まれていないので、シェルはスクリプトを見つけられません。Chapter 6 で習った command not found の原因切り分け の出番です。
command not found が出ず check-logins が動いた人へ: Chapter 6 で ~/.bashrc に PATH を追記済みだと、ログイン時点で ~/bin が $PATH に入っているため、ここはエラーになりません。それで正常です。下の「~/.bashrc へ追記」は すでに済んでいる ので、二重に足さず次の source 確認へ進んでください。~/.bashrc の末尾に追記:
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc tail -3 ~/.bashrc # → ... # → export PATH="$HOME/bin:$PATH"
>>
§ 1 で学んだとおり、> は 上書き なので echo '...' > ~/.bashrc と打つと ~/.bashrc の中身が 1 行だけのファイルに置き換わって全部消えます(Linux 初心者がやりがちな事故 No.1)。末尾に足したいときは必ず >> を使ってください。
vim ~/.bashrc で開いて Shift+G(最終行へジャンプ)→ o(下に新規行 / Ch5 で習った)→ 上の 1 行を入力 → Esc :wq でも同じ。vim で開けば既存の .bashrc を壊す心配がないので、心配なら vim 派でも OK。>> は実行するたびに 1 行ずつ足されます。やり直すときは先に grep PATH ~/.bashrc で確認し、既に同じ行があれば追記しないでください。重複しても動きますが、無駄なので 1 行に保つのが綺麗です。確実に 1 行だけにしたいなら次の「足す前に確認」型を使います:grep -q '$HOME/bin' ~/.bashrc || echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc(
|| = 左が失敗したときだけ右を実行。「まだ無ければ足す」というイディオム)設定を 今のシェルに反映 します:
source ~/.bashrc echo $PATH # → /home/student/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:... check-logins # → Failed logins: 4
~/bin が $PATH の先頭に追加され、check-logins が どこからでも呼べる ようになりました。
cp でバックアップ → 修正 → 動作確認 → rm で削除 動いているスクリプトを修正するときの 鉄則の流れ: ① cp でバックアップ → ② vim で修正 → ③ 動作確認 → ④ OK なら rm でバックアップ削除。.bak は Linux 文化のバックアップ慣習。Chapter 3 で触れた 「rm の現場の作法」 の意味がここで回収されます。「動いた瞬間に旧版を削除」することで、ディレクトリには常に 「今動いているバージョン 1 つだけ」 が残ります。改修の準備 ── cp でバックアップ → v2 に書き換え
v2 = version 2(改修版)。v1 に「日時」「成功ログイン数」を追加した 3 行スクリプトに育てます。
ここから 現場の作法 で v1 を v2 に育てます。まずバックアップ:
cd ~/bin cp check-logins check-logins.bak ls -la # → -rwxrwxr-x 1 student student 86 ... check-logins # → -rwxrwxr-x 1 student student 86 ... check-logins.bak
vim check-logins で v2 に書き換え。新仕様:
- 日付を入れる(
$(date)でコマンド置換) - Successful login の集計も足す
- 出力を 2 行に整形
#!/bin/bash echo "Failed logins on $(date): $(grep "Failed password" /var/log/auth.log | wc -l)" echo "Successful logins: $(grep "Accepted " /var/log/auth.log | wc -l)"
d + カーソル移動 G の合体技で「動いた範囲を削除」)→ i で入力。1 行だけ修正なら :N(N 行目にジャンプ)→ dd(その行削除)→ O(大文字オー = Chapter 5 で習った o(下に新規行)の 上向き版 / カーソル行の 上 に新規行)→ 入力 → Esc :wq。Chapter 5 で覚えたキーをここで使い込みます。動作確認 → rm で不要になったバックアップを削除
check-logins # → Failed logins on 2026年 5月 17日 日曜日 11:13:47 JST: 4 # → Successful logins: 7
新仕様で正しく動くことが確認できたら、もう check-logins.bak は不要です。現場の作法 に従って rm で削除します:
rm check-logins.bak ls -la # → -rwxrwxr-x 1 student student 169 ... check-logins
check-logins) 1 つだけ」 が残りました。「動作確認できたら、もう不要な check-logins.bak は rm で消す」 までで 1 回の改修作業 ── これが Chapter 3 章末で予告した「rm の現場の作法」の正体です。集計の中身を解剖 ── grep と wc -l と adm グループ
v2 の中身を 1 行ずつ解剖:
grep "Failed password" /var/log/auth.log | wc -l # → 4 grep "Accepted " /var/log/auth.log | wc -l # → 7
Chapter 4 で習った grep で探す → パイプ | で渡す → wc -l で行数を数える の組み合わせ。/var/log/auth.log は root と adm グループしか読めない ファイルです:
ls -la /var/log/auth.log # → -rw-r----- 1 syslog adm 10307 5月 17 11:13 /var/log/auth.log groups # → student adm
学習環境では adm は student に事前付与済みなので、ここは普通に読めます(Ch7 の種明かしを思い出してください)。一方、自分で構築した環境で adm 未付与だと、ここで cannot open /var/log/auth.log という 3 つ目のエラーに詰まります(Part 1 で覚えた 3 大エラーの最後)。その場合の復旧は exit → sudo usermod -aG adm student → 再 SSH です。
結果をファイルに残す ── > リダイレクト
check-logins > ~/report.txt ls -la ~/report.txt # → -rw-rw-r-- 1 student student 84 5月 17 11:13 /home/student/report.txt
画面には何も出ません。画面に出るはずだったものが ~/report.txt に流れた からです(この章で学んだ唯一の新概念)。
ゴール ── cat ~/report.txt でレポート確認
cat ~/report.txt Failed logins on 2026年 5月 17日 日曜日 11:13:47 JST: 4 Successful logins: 7
check-logins が、~/report.txt に 2 行のレポートを吐き出しました。「§ 06 次の章へ」 で Part 1 全体を振り返ります。| 起きたこと | 対処 |
|---|---|
~/bin/check-logins: 許可がありません | chmod +x ~/bin/check-logins で実行権限を付ける(STEP 05) |
bash: check-logins: コマンドが見つかりません | ~/.bashrc に export PATH="$HOME/bin:$PATH" を追記して source ~/.bashrc、または再ログイン(STEP 06) |
cannot open /var/log/auth.log: 許可がありません | groups で adm が見えるか確認。見えなければ exit → 再 SSH で新セッションを開く(学習環境では adm 事前付与済み) |
check-logins > ~/report.txt で ~/report.txt が空になった | ~/bin/check-logins 単体で出力が出るか先に確認。出ないなら chmod / PATH / adm のどれかが未解決 |
| v2 への書き換えに失敗 | cp ~/bin/check-logins.bak ~/bin/check-logins でバックアップから復元(STEP 07 で cp した意味) |
~/.bashrc を壊して新規ログインで打ち上げ失敗 | cp ~/.bashrc ~/.bashrc.bak を事前に取るのが安全策。壊した場合は nano ~/.bashrc でも開けるので余計な行を消す |
詰まったら
- 段階ヒント: 定番の詰まりポイントへの段階開示
- AI に相談: Cloudflare Workers AI に自由質問できる相談窓口(v2 公開予定)
💡 軽く方向だけ
~/bin/check-logins というファイルを作る → 実行できるようにする(chmod +x)→ コマンド名で呼べるようにする(PATH)→ 中身を $(...) を使って整形 → 結果を > でファイルに保存、の順に進みます。詰まりやすいのは Permission denied / command not found / cannot open auth.log の 3 つで、Chapter 5 / 6 / 7 のどこかで習った対処法で全部解決します。
💡 具体的な手順
# 接続 ssh student@learner01 # STEP 03 作る mkdir ~/bin touch ~/bin/check-logins # STEP 04 v1 を書く (vim) vim ~/bin/check-logins # 中身: # #!/bin/bash # echo "Failed logins: $(grep \"Failed password\" /var/log/auth.log | wc -l)" # STEP 05 実行権限 chmod +x ~/bin/check-logins ~/bin/check-logins # STEP 06 PATH 通す echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc source ~/.bashrc check-logins # STEP 07 v2 に改修 cd ~/bin cp check-logins check-logins.bak vim check-logins # v2 中身: # #!/bin/bash # echo "Failed logins on $(date): $(grep \"Failed password\" /var/log/auth.log | wc -l)" # echo "Successful logins: $(grep \"Accepted \" /var/log/auth.log | wc -l)" # STEP 08 動作確認 → 不要になったバックアップを rm で削除 check-logins rm check-logins.bak # STEP 10-11 リダイレクトで保存 → ゴール check-logins > ~/report.txt cat ~/report.txt
詰まりやすい 3 大エラー(Permission denied / command not found / cannot open auth.log)の対処は 右ペインの「3 大エラー早見表」 を参照。
✅ 答えを見る
完成版 ~/bin/check-logins(v2):
#!/bin/bash echo "Failed logins on $(date): $(grep "Failed password" /var/log/auth.log | wc -l)" echo "Successful logins: $(grep "Accepted " /var/log/auth.log | wc -l)"
完成版 ~/.bashrc 末尾の追記行:
export PATH="$HOME/bin:$PATH"
実行例:
$ check-logins > ~/report.txt $ cat ~/report.txt Failed logins on 2026年 5月 17日 日曜日 11:13:47 JST: 4 Successful logins: 7
この演習で踏んだ Part 1 の全要素:
| 章 | 使ったコマンド・概念 |
|---|---|
| Ch1 | ssh student@learner01 |
| Ch2 | cd ~ / ls -la / 隠しファイル |
| Ch3 | mkdir / touch / cp / rm |
| Ch4 | grep / wc -l / パイプ | |
| Ch5 | vim の i / :wq / dd / gg / dG |
| Ch6 | $PATH / ~/.bashrc / export / source |
| Ch7 | chmod +x / adm グループによる /var/log/auth.log アクセス |
| Ch8 | > リダイレクト / $() コマンド置換 / 現場の作法 |
AI に相談
修了確認
Part 1 の修了演習を締めくくる確認です。2 問だけ振り返ってみましょう。
check-logins を作って実行する過程で、人によっては次の 3 つのエラーに順番に出会います。それぞれの 原因 と 対処コマンド を答えてください(3 つ目は adm が付与されていない自前環境の人だけが見るエラーです):①
bash: /home/student/bin/check-logins: 許可がありません②
bash: check-logins: コマンドが見つかりません③
grep: /var/log/auth.log: 許可がありません> を >> に変えると何が変わりますか?(a) check-logins | wc -l(b) check-logins > ~/report.txt次の章へ
次は Part 2「ネットワーク基礎」 に進みます。Part 1 で「サーバの中で動くこと」を覚えたあなたが、次は 「サーバ同士をつなぐ」「ルーティングを理解する」 という視点を獲得していきます。
- Part 2 で扱うこと: ip コマンドでのネットワーク設定 / ARP と MAC / Linux Bridge(L2) / ルーティングと FRRouting(L3) / tc netem での遅延・パケットロス再現
- Part 3 で再会する道具: cron(あなたの
check-loginsを毎日自動化する)/ シェルスクリプト(複数行の自動化)/ systemd(サービス化)
~/bin/check-logins と ~/report.txt は 残しておいてください。Part 3 のはじめに、これを cron に登録して 毎日自動レポート に進化させます。grep で探す、vim で書く、PATH で道を通す、chmod で権限を整える、> で残す。これは「サーバ管理」の最小単位 です。