エラーの内容
シェルスクリプトを実行すると、次のエラーが表示されます:
$ ./deploy.sh
-bash: ./deploy.sh: /bin/bash^M: bad interpreter: No such file or directory
この ^M が問題の核心です。スクリプトにWindowsスタイルの改行コード(CRLF — \r\n)が含まれており、Unixスタイル(LF — \n)になっていません。
余分な \r 文字が原因で、Linuxはシェバンを #!/bin/bash\r と認識し、/bin/bash^M という名前のバイナリを探しに行きます。当然ながら、そのようなファイルは存在しません。
ほとんどの場合、Windowsで書かれたスクリプト、メモ帳で編集されたファイル、またはGitの core.autocrlf 設定がチェックアウト時に改行コードを自動変換したリポジトリからクローンしたときに発生します。
問題の確認
何かする前に、まず状況を確認しましょう。次のコマンドを実行します:
file deploy.sh
CRLFの改行コードを持つスクリプトは、明示的にそのように表示されます:
deploy.sh: Bourne-Again shell script, ASCII text executable, with CRLF line terminators
生の文字を確認したい場合は、cat -A を使うと可視化できます — 各行の $ の直前に ^M が表示されます:
cat -A deploy.sh | head -5
#!/bin/bash^M$
echo "Starting deploy..."^M$
この ^M$ のパターンが問題を確認します。修正しましょう。
修正方法
方法1:dos2unix(最速)
コマンド一つで完了:
dos2unix deploy.sh
スクリプトのディレクトリ全体を変換する場合は、一度にすべて変換できます:
dos2unix *.sh
または再帰的に — ネストされたシェルスクリプトを持つプロジェクトに便利:
find . -name "*.sh" -exec dos2unix {} \;
インストールされていない場合は、1行のコマンドで対応できます:
# Debian/Ubuntu
sudo apt install dos2unix
# RHEL/CentOS/Fedora
sudo yum install dos2unix
# macOS
brew install dos2unix
方法2:sed(追加ツール不要)
sed が使える場合は、キャリッジリターンを直接削除できます:
sed -i 's/\r//' deploy.sh
macOSの sed は少し異なり、-i の後に空文字列が必要です:
sed -i '' 's/\r//' deploy.sh
方法3:tr
古典的なUnixのアプローチ。一時ファイルに出力してから元に戻します:
tr -d '\r' deploy_fixed.sh
mv deploy_fixed.sh deploy.sh
chmod +x deploy.sh
方法4:vim
vimでファイルを編集中の場合は、エディタを離れずに修正できます:
:set ff=unix
:wq
修正の確認
file コマンドを再度実行します。正常なスクリプトはこのように表示されます — CRLFの記述がありません:
file deploy.sh
# deploy.sh: Bourne-Again shell script, ASCII text executable
cat -A で再確認:
cat -A deploy.sh | head -5
#!/bin/bash$
echo "Starting deploy..."$
行末が $ だけで ^M がありません。これで問題ありません。スクリプトを実行してください:
./deploy.sh
再発防止策
Gitの設定
根本的な原因は通常、Gitの core.autocrlf 設定です。Windowsでは、チェックアウト時にLFをCRLFに変換します。同僚がWindowsでリポジトリをチェックアウトすると、すべてのシェルスクリプトが知らずに破損してしまいます。
.gitattributes ファイルを使ってリポジトリレベルで設定を固定しましょう:
# .gitattributes
*.sh text eol=lf
*.bash text eol=lf
これを一度コミットすれば、以降はどのOSを使っていてもGitがシェルスクリプトのLF改行を強制します。
または、Windowsで作業していてGitの改行変換をグローバルに停止したい場合:
git config --global core.autocrlf input
このモードではチェックアウト時にLFを維持し、コミット時にCRLFをLFに変換します。クロスプラットフォームチームにとってより安全な設定です。
VS Code
ワークスペース設定(.vscode/settings.json)で新規ファイルのデフォルト改行コードをLFに設定します:
{
"files.eol": "\n"
}
VS Codeはステータスバー右下に現在のファイルの改行コードを表示します — CRLF または LF と表示され、クリックで即座に切り替えられます。
EditorConfig
リポジトリのルートに .editorconfig を配置します。ほとんどのモダンなエディタが自動的に認識します:
[*.sh]
end_of_line = lf
.gitattributes と組み合わせることで、編集とコミットの両方をカバーできます。
クイックリファレンス
- 最速の修正:
dos2unix yourscript.sh - 追加ツール不要:
sed -i 's/\r//' yourscript.sh - 根本的な原因: Windowsの改行コード(
\r\n)がシェバン行を汚染している - 長期的な修正:
*.sh text eol=lfを記述した.gitattributes

