
Linux環境でシェルスクリプトを実行しようとした際、ファイルは確かに存在し、権限も付与されているのに、なぜか実行できない…。そんな不可解なエラーに遭遇したことはありませんか?
今回は、特にWindowsとLinuxを併用している環境で発生しやすい、「目に見えない改行コード」によるトラブルとその解決策について解説します。
1. 発生したエラー
ターミナルでスクリプトを実行したところ、以下のようなエラーメッセージが表示されました。
foobar@your-machine:~/projects/onwindows$ ./your_script.sh -bash: ./your_script.sh: cannot execute: required file not found
「ファイルが見つからない」と言われていますが、lsコマンドで確認するとファイルは確実にそこにあります。パスの間違いでもありません。
ただ、そのディレクトリとファイルは、Windowsのファイルシステム上にあるものをWSL環境からリンクしていたので、もしかして改行コードが原因か?となりました。
2. エラーの原因:CRLF(Windows形式の改行)
あたりでした。Windows形式の改行コードである CRLF (\r\n) です。
Linuxの標準的な改行コードは LF (\n) です。Windowsで作成したファイルをそのままLinuxに持っていくと、スクリプトの1行目(シバン)が以下のように解釈されてしまいます。
想定している解釈:
#!/bin/bash実際の結果:
#!/bin/bash\r
システムは 「bash\r という名前のプログラム」 を探そうとしますが、当然そんなものは存在しません。そのため「(必要なプログラムである)ファイルが見つからない」というエラーが出ていたのです。
3. 解決方法:改行コードをLFに変換する
3.1. 原因の切り分け
まずは、本当に改行コードが原因か file コマンドで確認しましょう。
file your_script.sh
実行結果に with CRLF line terminators と表示されたら、改行コードの問題で確定です。
3.2. 修正コマンド(単体)
sed コマンドを使って、末尾の \r を一括削除するのが最も手軽です。
sed -i 's/\r$//' your_script.sh
また、dos2unix ツールがインストールされている場合は、より直感的に変換できます。
dos2unix your_script.sh
3.3 修正コマンド(複数):ディレクトリ内のファイルを一括チェック&修正
プロジェクト全体に同じ問題を抱えたファイルがないか不安な場合は、以下のコマンドが役立ちます。
CRLFのファイルを一括で「探す」
find . -name "*.sh" -exec file {} + | grep "CRLF"
見つかったファイルを一括で「修正する」
find . -name "*.sh" -exec sed -i 's/\r$//' {} +
4. 今後の対策:再発を防ぐために
「改行コード問題」を繰り返さないために、開発環境の設定を見直しましょう。
エディタ設定(VS Code等): 画面右下の改行コード表示が「CRLF」になっていたら「LF」に変更して保存する癖をつけましょう。
Gitの設定:
git config --global core.autocrlf inputを設定しておくことで、コミット時に自動的にLFに変換されるようになります。EditorConfigの導入: プロジェクトルートに
.editorconfigを置き、end_of_line = lfを指定しておくと、チーム全体で設定を統一できます。
まとめ
「ファイルはあるのに見つからない」という矛盾したエラーが出た時は、まずは改行コードを疑ってみてください。見えぬものでもあるんだよ。