【実践シェルスクリプト講座 第5回】「動かない…」で時間を溶かさないために。プロが教えるデバッグと安全対策の極意
こんにちは!「リナックス先生」です。
全5回にわたるこの講座も、ついに最終回を迎えました。
前回までは、バックアップやセキュリティ監視といった「動くもの」を作ってきましたが、コウ君、その後スクリプトの運用はどう?
先生、それが…手動で ./backup.sh って叩くと完璧に動くのに、Cronに登録した途端に動かなくなるんです!
あと、別のスクリプトでは変数の綴りを間違えていて、関係ないファイルを消しそうになって冷や汗をかきました…。
スクリプトって、動けばいいってもんじゃないんですね。
いい経験をしたわね、コウ君!
「手元で動く」と「無人で安全に動き続ける」の間には、実は大きな壁があるの。
最終回は、その壁を乗り越えるための「デバッグ技術」と「安全装置(エラーハンドリング)」、そして「Cronトラブルの解決法」を伝授するわ。
これをマスターすれば、あなたのスクリプトはプロレベルよ!
「実践シェルスクリプト講座」最終回のテーマは、「品質と信頼性」です。
どんな状況でも誤動作せず、もしエラーが起きても安全に停止し、原因をすぐに特定できる。そんな「堅牢なスクリプト」を書くためのノウハウを総まとめします。
本講座のカリキュラム(全5回)
これが最後の講義です。今まで作成したスクリプトをブラッシュアップしていきましょう。
- サーバー停止の恐怖から解放!「ディスク容量監視」と「ログ自動整理」の完全自動化
- データ消失をゼロにする!「堅牢バックアップ」と「Slack通知」の構築
- 手作業を撲滅せよ!「ユーザー一括作成」と「SSH鍵配布」の自動化スクリプト
- 攻撃者を秒でブロック!ログ解析による「SSH総当たり攻撃」自動防御システム
- 【今回】プロの品質へ!スクリプトの「安全性向上(デバッグ)」と「トラブルシューティング」
1. 「なぜ動かない?」を秒で解決するデバッグ技術
スクリプトが思った通りに動かない時、コードをじっと睨んでいても答えは出ません。
「今、どこを実行しているか」「変身には何が入っているか」を可視化するのがデバッグの基本です。
最強のオプション「bash -x」
スクリプトを実行する際、-x オプション(eXecution trace)を付けると、実行されるコマンドとその引数が全て画面に表示されます。
例:動きがおかしいスクリプト (debug_test.sh)
#!/bin/bash
USER="tanaka"
echo "Hello $USER"
if [ "$USER" = "suzuki" ]; then
echo "あなたは鈴木さんです"
fi
デバッグ実行
[root@localhost ~]# bash -x debug_test.sh + USER=tanaka + echo 'Hello tanaka' Hello tanaka + '[' tanaka = suzuki ']'
行頭に + がついているのが、実際に実行されたコマンドです。
変数 $USER が tanaka に展開されていることや、if 文の比較が行われている様子が手に取るようにわかりますね。
「変数が空っぽだった」「if文の条件が間違っていた」といったバグは、これ一発で見抜けます。
2. 事故を防ぐ!プロが必ず書く「3つの呪文」
シェルスクリプトは、デフォルトでは「エラーが起きても無視して次の行に進む」という、ある意味で恐ろしい仕様になっています。
これを防ぎ、他のプログラミング言語のように「エラー即停止」させるために、スクリプトの冒頭には必ず以下の「おまじない」を書きましょう。
安全宣言セット
#!/bin/bash set -euo pipefail
それぞれの意味を解説します。
① set -e (errexit)
効果: コマンドが1つでも失敗(終了コードが0以外)したら、その場でスクリプトを強制終了します。
メリット: 例えば cd /var/log/app に失敗したのに、そのまま rm -rf * を実行してしまい、カレントディレクトリ(全然違う場所)のファイルを全消去する…といった大事故を防げます。
② set -u (nounset)
効果: 未定義の変数を使おうとしたらエラーにして停止します。
メリット: スペルミスによる事故を防ぎます。
💀 恐怖の事例:もし set -u がなかったら…
DIR="/var/www/html" # 変数名を間違えて "DIR" ではなく "D" と打ってしまった! rm -rf "$D/"
set -u がないと、$D は「空文字」として扱われます。
するとコマンドは rm -rf / と解釈され、サーバーの中身が全て消えます。set -u があれば、「$D: unbound variable」というエラーが出て止まるので、命拾いします。
③ set -o pipefail
効果: パイプライン(cmd1 | cmd2)の途中でエラーが起きた場合でも、全体を「失敗」とみなします。
メリット: 通常、bashはパイプの最後のコマンドが成功すれば「成功」とみなします。mysqldump | gzip > backup.gz のような処理で、DBバックアップに失敗してもgzipが成功すれば「正常終了」と判定されてしまい、「空っぽのバックアップファイル」ができてしまうのを防ぎます。
3. 「Cronで動かない」あるあるトラブル解決法
コウ君が遭遇した「手動なら動くのにCronだと動かない」現象。
これには明確な3つの原因があります。
原因1:環境変数 PATH が通っていない
Cron実行時は、非常に最小限のPATHしか設定されていません。
そのため、rsync や docker、aws といった追加コマンドが見つからずにエラーになります。
【対策】 スクリプト内でPATHを明示的に定義する。
#!/bin/bash # 必要なパスを全部書いておく export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
原因2:カレントディレクトリが違う
Cronはユーザーのホームディレクトリ(/root や /home/user)から実行されます。
スクリプト内で相対パス(./data.txt など)を使っていると、ファイルが見つかりません。
【対策】 最初にスクリプトのある場所に移動する。
# スクリプト自身のディレクトリに移動 cd "$(dirname "$0")"
原因3:出力が見えない
Cronのエラー出力は、設定しないと捨てられてしまいます(あるいはメールで届きますが、見逃しがちです)。
【対策】 ログファイルに標準出力とエラー出力を両方書き込む。
# crontab -e の設定例 # >> (追記) と 2>&1 (エラーも標準出力にマージ) を使う 0 3 * * * /root/scripts/backup.sh >> /var/log/backup.log 2>&1
4. その他の「ハマりポイント」総まとめ
Windowsで書いたスクリプトが動かない(改行コード問題)
Windowsのメモ帳などでスクリプトを書いてサーバーにアップロードすると、改行コードが CR+LF になり、Linuxではエラー($'\r': command not found)になります。
Linuxの改行コードは LF です。
【対策】 nkf コマンドなどで変換するか、VSCodeなどのエディタで「LF」指定で保存しましょう。
if文のスペース忘れ
シェルスクリプトの [ はただの括弧ではなく、test というコマンドの略称です。
そのため、前後に必ずスペースが必要です。
# × ダメな例(くっついている) if ["$a"="$b"]; then # ○ 正しい例(スペースがある) if [ "$a" = "$b" ]; then
講座のまとめ:自動化の先にあるもの
全5回にわたり、実践的なシェルスクリプトの書き方を学んできました。
| 回 | テーマ | 習得スキル |
|---|---|---|
| 第1回 | 監視・掃除 | 変数、条件分岐、cron |
| 第2回 | バックアップ | tar/rsync、通知機能 |
| 第3回 | ユーザー管理 | ループ処理、テキスト解析 |
| 第4回 | セキュリティ | ログ解析(awk)、ファイアウォール |
| 第5回 | 品質向上 | デバッグ、エラーハンドリング |
これらのスクリプトは、単に「楽をするため」だけのものではありません。
人間がやるべきでない単純作業を機械に任せることで、ミスをなくし、空いた時間で「よりクリエイティブな仕事」や「新しい技術の習得」に時間を使うためにあるのです。
先生、ありがとうございました!
最初は黒い画面が怖かったけど、今は自分でスクリプトを書いて、サーバーが思い通りに動くのが楽しくて仕方ありません。
今回教わったデバッグ方法を使って、これまでのスクリプトも全部 set -eu を入れて書き直してみます!
素晴らしい心がけね、コウ君!
「動けばいい」から「安全に動く」へ意識が変わったなら、あなたはもう立派なインフラエンジニアよ。
Linuxの世界は奥深いわ。これからも失敗を恐れずに、どんどん自動化にチャレンジしてね!
これで「実践シェルスクリプト講座」は完結です。
しかし、技術の旅は終わりません。
ぜひ、あなた自身の専用サーバー(VPS)を手に入れて、思う存分実験し、自分だけの最強ツールを作り上げてください。
あなたのエンジニアライフが、より快適で楽しいものになりますように!
▼安全に実験するなら、壊してもすぐ直せるVPSで!


コメント