今回は、RHELでシェルスクリプトやバッチジョブが突然失敗する原因の一つである「非表示の改行コード」問題について解説します。この問題は、特にWindows環境からLinux環境にファイルを移行した際や、異なるエディタでファイルを編集した際に頻発するトラブルです。
なぜ改行コードが問題になるのか?
LinuxとWindowsでは、改行コードの表現方法が異なります:
- Linux/Unix: LF(Line Feed: \n)
- Windows: CR+LF(Carriage Return + Line Feed: \r\n)
この違いにより、以下のような問題が発生します:
実際のトラブル事例
- シェルスクリプト実行時に「command not found」エラー
- 設定ファイルのパス指定が認識されない
- バッチジョブが予期せず失敗する
- 環境変数が正しく設定されない
1. fileコマンドによる事前確認
まず、対象ファイルの改行コードを確認しましょう。
# ファイルの改行コードを確認
file -b filename.sh
# 結果例
# ASCII text, with CRLF line terminators ← Windows形式
# ASCII text ← Linux形式
この方法で、事前にファイルの改行コード形式を把握できます。
2. viエディタでの改行コード表示と修正
改行コードの可視化
# viエディタでファイルを開く
vi filename.sh
# コマンドモードで改行コードを表示
:set list
この設定により、以下のように改行コードが表示されます:
$
: 通常の改行(LF)^M$
: Windows形式の改行(CR+LF)
viエディタでの修正方法
# viエディタ内で改行コードを一括変換
:%s/\r$//g
# 変更を保存
:wq
解説: \r
はCR(Carriage Return)を表し、$
は行末を意味します。この置換により、行末のCRを削除します。
3. sedコマンドによる改行コード変換
基本的な変換方法
# CR+LFをLFに変換(新しいファイルを作成)
sed 's/\r$//' filename.sh > filename_fixed.sh
# 元ファイルを直接変更(-iオプション)
sed -i 's/\r$//' filename.sh
複数ファイルの一括処理
# 指定ディレクトリ内の全.shファイルを変換
find /path/to/directory -name "*.sh" -exec sed -i 's/\r$//' {} \;
# 特定の拡張子のファイルを一括変換
for file in *.sh *.conf *.txt; do
sed -i 's/\r$//' "$file"
done
4. トラブルシューティングの実践手順
Step 1: 問題の特定
# 1. エラーが発生しているファイルの確認
file -b error_script.sh
# 2. 改行コードの可視化
vi error_script.sh
:set list
Step 2: 修正作業
# 3. バックアップ作成
cp error_script.sh error_script.sh.bak
# 4. 改行コード修正
sed -i 's/\r$//' error_script.sh
# 5. 修正確認
file -b error_script.sh
Step 3: 実行確認
# 6. スクリプトの実行権限確認
chmod +x error_script.sh
# 7. 実行テスト
./error_script.sh
5. 予防策と運用のベストプラクティス
ファイル転送時の注意点
# FTPでバイナリモードで転送
ftp> binary
ftp> put filename.sh
# SCPでの転送(推奨)
scp filename.sh user@server:/path/to/destination/
開発環境での設定
# .bashrcに改行コードチェック関数を追加
check_newline() {
echo "Checking newline characters in $1:"
file -b "$1"
echo "---"
sed -n 'l' "$1" | head -5
}
6. エラーメッセージ別対処法
「command not found」エラー
# シバン行に余分な文字が含まれている可能性
head -1 script.sh | od -c
# 0000000 # ! / b i n / b a s h \r \n
「No such file or directory」エラー
# パス指定に見えない文字が含まれている
cat -A config.conf | grep path
# path=/usr/local/bin^M$
まとめ
改行コード問題は、遭遇しやすいトラブルの一つですが、適切な手順で対処すれば確実に解決できます。重要なのは以下の3点です:
- 事前確認:
file
コマンドで改行コード形式を把握 - 可視化:
vi
エディタの:set list
で問題箇所を特定 - 修正:
sed
コマンドで確実に変換
これらの手順を覚えておけば、同様の問題に遭遇した際に迅速に対応できます。また、定期的にファイルの改行コードをチェックする習慣をつけることで、トラブルを未然に防ぐことができます。
サーバー運用において、このような基本的なトラブルシューティング技術は非常に重要です。今回紹介した手順を実際の環境で試してみて、いざという時に備えてください。
コメント