【新・実践シェルスクリプト講座 番外編】スクリプトが動かない? エラーが出た? そんな時の「虎の巻」
こんにちは!「リナックス先生」です。
全4回の「新・実践シェルスクリプト講座」、完走お疲れ様でした!
コウ君、その後スクリプトを運用していて、何か困ったことは起きてない?
先生!基本的には順調なんですが…
Windowsで編集したファイルをアップロードしたら動かなくなったり、Cronに登録したら「command not found」ってエラーが出たり、細かいトラブルに遭遇しています。
あと、第1回の sed コマンド、記号がいっぱいで正直よくわかってません!(涙)
それはスクリプト初心者が必ず通る道ね。
今回は番外編として、全4回の記事に対する「補足解説」と、よくあるエラーを解決するための「トラブルシューティング」をまとめるわ。
これを読めば、なぜ動かなかったのかがスッキリ分かるはずよ!
本記事は、これまでの講座(全4回)で作成したスクリプトを、より深く理解し、安全に動作させるための補足・修正記事です。
特に「Cronのパス問題」や「テキスト処理の罠」など、現場で必ず役立つ知識を網羅しました。
講座アーカイブ
各回の記事はこちらから確認できます。
共通トラブル:Windowsで編集すると動かない問題
現象:
スクリプトを実行すると /bin/bash^M: bad interpreter や command not found といった謎のエラーが出る。
原因:
Windowsのメモ帳などで編集すると、改行コードが CRLF (Windows用) になってしまいます。
Linuxのシェルスクリプトは LF (Unix用) でないと動作しません。
【解決策】改行コードを変換する
サーバー上で以下のコマンドを使って修復できます。
# dnf install -y dos2unix (入っていない場合) dos2unix my_script.sh
または、VSCodeなどのエディタ側で、右下の「CRLF」をクリックして「LF」に変更してから保存しましょう。
第1回(構築自動化)の補足・解説
補足:sedコマンドの「区切り文字」は変えられる
第1回で、パス(URLやディレクトリ)を置換する際にバックスラッシュ \/ でエスケープしました。
しかし、スラッシュが多いと読みづらいですよね。
# 読みにくい例(スラッシュをエスケープしている) sed -i 's/\/var\/www\/html/\/opt\/web/g' config.conf
実は、sed の区切り文字は / 以外も使えます。# や | を使うとスッキリします。
# 読みやすい例(#を使っている) sed -i 's#/var/www/html#/opt/web#g' config.conf
修正:dnf/yum のロック問題
自動構築スクリプトを実行した際、バックグラウンドで自動アップデート機能(dnf-automaticなど)が動いていると、Waiting for process with pid... と表示されて止まってしまうことがあります。
これを防ぐには、スクリプトの冒頭で「ロックが解除されるまで待つ」処理を入れるのが親切です。
# ロック解除待ちループ(簡易版)
while fuser /var/lib/rpm/.dbenv.lock >/dev/null 2>&1; do
echo "他のプロセスがyum/dnfを使用中です。待機しています..."
sleep 5
done
第2回(監視・復旧)の補足・解説
重要:Discord/Slack通知の「エスケープ」処理
記事内のスクリプトでは簡易的にJSONを作っていましたが、もしログメッセージの中にダブルクォート " や改行コードが含まれていると、JSONの形式が壊れて通知が届きません。
【解決策】jqコマンドを使う(推奨)
実務では、jq コマンドを使って安全にJSONを作るのが鉄則です。
# dnf install -y jq
# 安全なJSON生成
payload=$(jq -n --arg content "メッセージ" '{"content": $content}')
curl -H "Content-Type: application/json" -X POST -d "$payload" "$DISCORD_URL"
補足:通知がうるさすぎる場合
5分おきに「失敗しました」と通知が来ると、オオカミ少年状態になります。
「前回失敗通知を送ってから1時間は送らない」といった制御をするには、一時ファイル(フラグファイル)を使います。
FAIL_FLAG="/tmp/monitoring_failed.flag"
# 失敗時
if [ ! -f "$FAIL_FLAG" ]; then
send_discord "失敗しました!"
touch "$FAIL_FLAG" # フラグ作成
fi
# 復旧時
if [ -f "$FAIL_FLAG" ]; then
send_discord "復旧しました!"
rm -f "$FAIL_FLAG" # フラグ削除
fi
第3回(AWSバックアップ)の補足・解説
重要:AWS IAM権限は「最小限」に
記事では触れませんでしたが、AWS CLIに設定するアクセスキーには、「AmazonS3FullAccess」などの強い権限を与えてはいけません。
万が一サーバーが乗っ取られた場合、S3内の全データを消されてしまうリスクがあります。
【推奨】バケット限定ポリシー
「特定のバケットへの書き込みだけ」を許可するIAMポリシーを作成して割り当てましょう。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-server-backup-bucket",
"arn:aws:s3:::my-server-backup-bucket/*"
]
}
]
}
トラブルシュート:Cronでawsコマンドが見つからない
aws コマンドは /usr/local/bin/aws にインストールされることが多いですが、Cronの環境変数にはここが含まれていないことがあります。
スクリプト内ではフルパスで書くのが確実です。
# × aws s3 cp ... # ○ /usr/local/bin/aws s3 cp ...
第4回(対話ツール)の補足・解説
補足:select文を使ったメニュー作成
記事では echo と read でメニューを作りましたが、Bashにはメニュー専用の select 構文もあります。
機能はシンプルですが、記述量は劇的に減ります。
PS3="コマンドを選んでください > "
select cmd in "Status" "Log" "Restart" "Exit"; do
case $cmd in
"Status") show_status ;;
"Log") monitor_log ;;
"Restart") restart_services ;;
"Exit") break ;;
*) echo "無効な選択です" ;;
esac
done
小技:文字色をつけて見やすくする
tput コマンドを使うと、文字に色を付けられます。
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
RESET=$(tput sgr0)
echo "${GREEN}成功しました!${RESET}"
echo "${RED}エラーが発生しました!${RESET}"
まとめ:エラーこそが成長の糧
今回の番外編では、より実践的なテクニックとトラブルシューティングを紹介しました。
| 対象 | ポイント | プロの処方箋 |
|---|---|---|
| 全体 | Windowsで編集してエラー | dos2unix で改行コード変換 |
| 第1回 | sedの区切り文字 | / 以外(#など)を使うと見やすい |
| 第2回 | 通知JSONエラー | jq コマンドを使う |
| 第3回 | AWSセキュリティ | IAM権限をバケット限定にする |
なるほど…!
Windowsの改行コード問題、まさにそれでハマってました!
エラーが出ても焦らずログを見れば、原因は必ずあるんですね。
その通り!
プログラミングにおいて、エラーメッセージは「敵」ではなく、問題を教えてくれる「親切な案内板」なの。
今回学んだ知識を武器に、どんどん新しいスクリプトに挑戦してみてね!
これで「新・実践シェルスクリプト講座」シリーズは本当に完結です。
あなたのサーバーエンジニアとしての旅が、トラブル少なく、楽しいものになることを祈っています!
▼安全に実験するなら、壊してもすぐ直せるVPSで!


コメント