【Bash講座 付録】講座は終わっても、旅は続く。スクリプト完全解説&便利帳
こんにちは!「リナックス先生」です。
全12回のBash講座、本当にお疲れ様でした!
コウ君、その後サーバー管理ライフはどう?
先生!おかげさまで、簡単な自動化は自分で書けるようになりました!
でも、いざ自分で新しいツールを作ろうとすると「あれ? if文の書き方どうだっけ?」とか「変数の引用符ってどっちだっけ?」ってなっちゃって、過去の記事を行ったり来たりしてます…。
一箇所にまとまった「カンペ」みたいなのが欲しいなぁ、なんて。
ふふ、エンジニアあるあるね。
「暗記」なんてしなくていいの。必要な時にすぐに調べられる「リファレンス(辞書)」を持っておくことが大事よ。
今回は、講座で登場したスクリプトの「行ごとの超・詳細解説」と、講座では紹介しきれなかった「現場で使えるワンライナー集」をまとめたわ。
困ったときはこの記事に戻ってくれば解決する、そんな「保存版」として使ってね!
この付録記事では、全12回の連載で作成したスクリプトを体系的に整理し、さらに実務で役立つ知識を追加しました。
ブックマークして、辞書代わりに活用してください。
目次:Bash講座 知識の総まとめ
- 基礎スクリプト解説:変数、引数、コマンド置換
- 制御構文スクリプト解説:条件分岐(if)、ループ(for, while)
- 実践ツール解説:バックアップ、監視、ログ解析
- 現場で使えるワンライナー集:コマンド1行で仕事を終わらせる技術
- 特殊変数・演算子リファレンス:忘れがちな記号の意味一覧
- トラブルシューティング:よくあるエラーと対処法
1. 基礎スクリプト解説
第7回で学んだ、シェルスクリプトの最も基本的な形です。
「変数の扱い」と「引用符」は、ベテランでもミスしやすいポイントです。
変数とコマンド置換 (hello.sh / myvar.sh)
#!/bin/bash
# 1. 変数への代入
# 注意:=の前後にスペースを入れてはいけない!
NAME="Linux"
# 2. コマンド置換
# コマンドの実行結果を変数に入れる
TODAY=$(date +%Y-%m-%d)
# 3. 変数の展開
# 変数の中身を取り出すときは $ をつける
echo "Hello, ${NAME} Server!"
echo "Today is $TODAY"
🔍 コード深掘り解説
#!/bin/bash(Shebang)
1行目に必ず書くおまじない。「このファイルはBashで実行します」という宣言です。#!/bin/shと書くこともありますが、Bash特有の機能(配列など)を使う場合はbashと明記するのが安全です。${NAME}(ブレース)
変数は$NAMEでも動きますが、${NAME}と波括弧で囲む癖をつけましょう。
例えば${NAME}Serverと書けば「NAME変数の中身 + Server」となりますが、$NAMEServerと書くと「NAMEServerという変数」を探してしまい、空っぽになってしまいます。$(command)(コマンド置換)
昔はバッククォート`command`が使われていましたが、入れ子にするのが難しいため、現在は$(...)が推奨されています。
引数の利用 (greet.sh)
スクリプト実行時に渡された値を受け取る方法です。
#!/bin/bash echo "Script Name: $0" echo "Hello, $1!" echo "Your favorite food is $2."
🔍 コード深掘り解説
- 実行例:
./greet.sh Alice Apple $0→./greet.sh(スクリプト自身の名前)$1→Alice(1つ目の引数)$2→Apple(2つ目の引数)- もし引数がなかったら?
中身が空になるだけです。必須入力にしたい場合は、後述するif文でチェックする必要があります。
2. 制御構文スクリプト解説
プログラムに「知能」を与える制御構文。
構文エラーになりやすい「スペース」の位置に注意しましょう。
条件分岐 (if文)
「もし〜なら」を記述します。
#!/bin/bash
FILE="config.txt"
# [ ] の内側には必ずスペースが必要!
if [ -f "$FILE" ]; then
echo "$FILE は存在します。"
else
echo "エラー: $FILE が見つかりません。"
# スクリプトを異常終了(1)させる
exit 1
fi
🔍 コード深掘り解説
[ -f "$FILE" ]
[は実はコマンドです。だから引数を区切るためのスペースが必須なのです。
変数をダブルクォート"$FILE"で囲むのは、もしファイル名にスペースが含まれていたり、変数が空だったりした場合の誤動作を防ぐためです(超重要テクニック)。exit 1
スクリプトを途中で止めたい時に使います。0は成功、1〜255はエラーを表します。
繰り返し処理 (for文)
「あるリストの分だけ繰り返す」処理です。
#!/bin/bash
# ワイルドカード展開を利用
for FILE in *.log
do
echo "Processing $FILE ..."
mv "$FILE" "${FILE}.bak"
done
🔍 コード深掘り解説
for FILE in *.log
シェルが*.logを「error.log access.log app.log」のようにファイル名リストに展開し、それを順番に処理します。
ファイルがない場合、*.logという文字そのものが変数に入ってしまうことがあるため、厳密にはnullglobオプションなどで制御することもあります。
3. 実践ツール解説
第11回で作った、実務レベルのスクリプトです。
これをコピペしてCronに仕込めば、あなたはもう「手動バックアップ」から解放されます。
世代管理バックアップ (backup.sh)
#!/bin/bash
set -euo pipefail # 安全装置(エラーで即停止)
BACKUP_DIR="/backup"
TARGET="/var/www/html"
DATE=$(date +%Y%m%d)
FILENAME="backup_${DATE}.tar.gz"
# 1. バックアップ作成
tar zcf "${BACKUP_DIR}/${FILENAME}" "$TARGET"
# 2. 古いファイルの削除(7日以上前)
# find の -mtime +7 は「8日前以前」を意味する
find "$BACKUP_DIR" -type f -name "*.tar.gz" -mtime +7 -delete
🔍 コード深掘り解説
set -euo pipefail
第12回で紹介した「プロの作法」。-e: エラーで停止、-u: 未定義変数で停止、-o pipefail: パイプ途中のエラーも検知。
バックアップのような重要処理では、途中で失敗したのに「成功しました」顔で進まれるのが一番困るので、必ず入れましょう。find ... -delete
非常に強力なコマンドです。テストする時は-deleteを外して実行し、消えるファイルを確認してからつけるのが安全です。
ディスク容量監視 (disk_check.sh)
#!/bin/bash
# 使用率が90%を超えたらアラート
THRESHOLD=90
# dfコマンドの結果を加工して数字だけ取り出す
# sed 's/%//' でパーセント記号を削除
USE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$USE" -ge "$THRESHOLD" ]; then
echo "Warning: Disk usage is ${USE}%" | mail -s "Disk Alert" admin@example.com
fi
🔍 コード深掘り解説
awk 'NR==2 {print $5}'
dfコマンドの出力の「2行目(NR==2)」の「5列目($5)」を取り出します。
ヘッダー行(1行目)を無視するためのテクニックです。
4. 現場で使えるワンライナー集
スクリプトファイルを作るほどでもないけれど、手作業だと面倒。
そんな時に、コマンドラインでサッと打って解決する「ワンライナー」を紹介します。
これを空で打てると「おっ、できるな」と思われます。
ログ解析系
特定のIPアドレスからのアクセス数をカウントしてランキング
cat access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -10
第10回で紹介した黄金パターン。攻撃者の特定などに役立ちます。
ログファイルからエラー行だけを抜き出してリアルタイム監視
tail -f app.log | grep --line-buffered "ERROR"
--line-buffered をつけると、grepがバッファリング(溜め込み)せずに即座に出力してくれるので、監視に向いています。
ファイル操作系
ディレクトリ内のファイル一括リネーム(.txt -> .bak)
for f in *.txt; do mv "$f" "${f%.txt}.bak"; done
${f%.txt} は「末尾の.txtを削除する」という変数展開テクニックです。
空のディレクトリを一括削除
find . -type d -empty -delete
掃除に便利です。
カレントディレクトリの合計サイズを表示
du -sh .
-s: 合計のみ、-h: 人間に読みやすい単位(GB, MB)で表示。
システム管理系
メモリを食っているプロセスTOP5を表示
ps aux | sort -rnk 4 | head -5
-k 4 は4列目(メモリ使用率)でソートするという意味です。
古いログファイルを圧縮する(30日以上前)
find /var/log -name "*.log" -mtime +30 -exec gzip {} \;
-exec を使うと、見つけたファイルに対してコマンドを実行できます。
5. 特殊変数・演算子リファレンス
「あれ? $# ってなんだっけ?」「-ne ってどっちだっけ?」
そんな時のための早見表です。
特殊変数
| 変数 | 意味 |
|---|---|
$0 |
実行中のスクリプト名 |
$1 ~ $9 |
引数(1番目〜9番目) |
$# |
引数の合計個数 |
$@ |
全引数のリスト(for文でよく使う) |
$? |
直前のコマンドの終了ステータス(0:成功, 1:失敗) |
$$ |
現在のプロセスID(一時ファイル名によく使う) |
数値比較演算子(if [ $a 〇〇 $b ])
| 演算子 | 意味 | 英語の覚え方 |
|---|---|---|
-eq |
等しい (=) | equal |
-ne |
等しくない (!=) | not equal |
-gt |
より大きい (>) | greater than |
-lt |
より小さい (<) | less than |
-ge |
以上 (>=) | greater or equal |
-le |
以下 (<=) | less or equal |
ファイルテスト演算子(if [ 〇〇 “$FILE” ])
| 演算子 | 意味 |
|---|---|
-e |
存在する (Exist) |
-f |
ファイルである (File) |
-d |
ディレクトリである (Directory) |
-r |
読み取り可能 (Readable) |
-w |
書き込み可能 (Writable) |
-x |
実行可能 (eXecutable) |
-s |
サイズが0より大きい(空ファイルではない) |
6. トラブルシューティング:動かない時はここを見ろ!
先生、書いたスクリプトが動かない時、画面にエラーが出るんですけど英語でよくわかりません…。
よくあるエラーってどんなのがありますか?
エラーメッセージは「答え」そのものよ。
よく見るエラーBest3をまとめたから、これが出たら「あ、あれね」と思えるようになりましょう。
1. Permission denied(許可がありません)
- 原因: 実行権限がない、または読み書き権限がない。
- 対処:
- スクリプト自体なら:
chmod +x script.sh - ファイル操作なら:
sudoをつけるか、chownで所有者を自分にする。
- スクリプト自体なら:
2. Command not found(コマンドが見つかりません)
- 原因:
- タイプミス(
echooとか) - PATHが通っていない(Cronでよくある)
- 変数の中身が空で、変なコマンドとして解釈されている
- タイプミス(
- 対処:
- スペル確認。
- Cronならフルパス(
/usr/bin/python)で書く。 - 変数を
echoで表示してデバッグする。
3. syntax error: unexpected end of file
- 原因: 文法エラー。特に「閉じ忘れ」。
ifに対するfiがない。doに対するdoneがない。- クォート
"が閉じられていない。
- 対処: インデント(字下げ)を綺麗に揃えると発見しやすい。エディタのシンタックスハイライトを活用する。
【奥義】デバッグモード
どこでエラーが出ているか分からない時は、実行時に -x オプションをつけます。
bash -x ./script.sh
実行されたコマンドが全て画面に表示されるので、どこで止まったか一目瞭然です。
終わりに:このページの使い方
Bashの文法は独特で、ベテランエンジニアでも「あれ?if文の括弧ってスペース要るっけ?」と忘れることは日常茶飯事です。
そんな時に、Google検索で怪しい記事を探すのではなく、この「付録」に戻ってきてください。
ここにあるのは、リナックス先生とコウ君が全12回で積み上げてきた「信頼できる知識」の結晶です。
コピー&ペーストして、自分なりに改造して、どんどん便利なツールを作ってください。
あなたのエンジニアライフが、シェルスクリプトによってより自由でクリエイティブなものになることを願っています。
Good Luck!
▼学んだ知識をすぐに試せる!推奨VPS

コメント