シェルスクリプトのホワイトスペース問題をデバッグ
「command not found」などの不可解なエラーを引き起こすシェルスクリプト内のCRLF改行コード、BOM文字、隠れたホワイトスペースを検出します。
Debugging
詳細な説明
シェルスクリプトと不可視文字
シェルスクリプトは不可視文字に特に敏感です。シェルインタープリタはそれらをコマンド、引数、制御フローの一部として扱うためです。1つの不適切な不可視文字が動作するスクリプトを不可解なエラーを出すものに変えてしまいます。
クラシックなCRLF問題
最も一般的なシェルスクリプトのホワイトスペース問題はCRLF改行コードです:
#!/bin/bash\r # \rは不可視だが存在する
echo "hello"\r # bashは次のように解釈:echo "hello"\r
表示されるエラー:
/bin/bash^M: bad interpreter: No such file or directory\r: command not foundsyntax error near unexpected token
シェルスクリプトのBOM
シェルスクリプトの先頭のBOMはシバンを無効にします:
[BOM]#!/bin/bash # カーネルがインタープリタを見つけられない
BOMは3バイト(EF BB BF)で、カーネルが#!の前に読み取るため、スクリプトの実行に失敗します。
コマンド内のNBSP
コマンド内のノーブレークスペースは正しく見えますが正しくありません:
apt-get install nginx # NBSP:"apt-get install"が見つからない
if [ -f file.txt ]; then # テストブラケット内のNBSP
変数内の末尾ホワイトスペース
PORT=8080· # 末尾スペース:PORTは"8080"ではなく"8080 "
curl http://localhost:$PORT/api # ポート"8080 "を試行 — 失敗
デバッグワークフロー
- スクリプトをホワイトスペースビジュアライザーに貼り付けます。
- 改行コードを確認:「LF (N)」のみであるべきです。CRLFは変換が必要です。
- BOMを確認:先頭で[BOM]を探します。
- NBSPを確認:コマンドやパス内の°マーカーをスキャンします。
- 末尾ホワイトスペースを確認:行末の·マーカーを探します。
- すべての問題のある文字をクリーンアップして修正されたスクリプトをコピーします。
予防
- エディタで
.shファイルにLF改行コードを使用するよう設定 .editorconfigに追加:[*.sh] end_of_line = lf.gitattributesに追加:*.sh text eol=lfshellcheckを使用して一般的なスクリプトの問題を検出
ユースケース
CI/CDパイプラインが開発者のMacでは動作するデプロイスクリプトをLinuxビルドサーバーで「command not found」エラーで実行します。ホワイトスペースビジュアライザーが、Windowsチームメイトの編集で導入されたCRLF改行コードとエディタからのBOMを検出します。LFに変換しBOMを除去するとパイプラインが修正されます。