シェルスクリプトのホワイトスペース問題をデバッグ

「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 found
  • syntax 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 "を試行 — 失敗

デバッグワークフロー

  1. スクリプトをホワイトスペースビジュアライザーに貼り付けます。
  2. 改行コードを確認:「LF (N)」のみであるべきです。CRLFは変換が必要です。
  3. BOMを確認:先頭で[BOM]を探します。
  4. NBSPを確認:コマンドやパス内の°マーカーをスキャンします。
  5. 末尾ホワイトスペースを確認:行末の·マーカーを探します。
  6. すべての問題のある文字をクリーンアップして修正されたスクリプトをコピーします。

予防

  • エディタで.shファイルにLF改行コードを使用するよう設定
  • .editorconfigに追加:[*.sh] end_of_line = lf
  • .gitattributesに追加:*.sh text eol=lf
  • shellcheckを使用して一般的なスクリプトの問題を検出

ユースケース

CI/CDパイプラインが開発者のMacでは動作するデプロイスクリプトをLinuxビルドサーバーで「command not found」エラーで実行します。ホワイトスペースビジュアライザーが、Windowsチームメイトの編集で導入されたCRLF改行コードとエディタからのBOMを検出します。LFに変換しBOMを除去するとパイプラインが修正されます。

試してみる — Whitespace Visualizer

フルツールを開く