WSL2でWindowsのシェルスクリプトが動かない原因|改行コード(CRLF・LF)の違いとdos2unixで解決する方法

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)【Linux入門】初心者のための基礎知識・講座 > WSL2でWindowsのシェルスクリプトが動かない原因|改行コード(CRLF・LF)の違いとdos2unixで解決する方法
「WSL2でシェルスクリプトを実行したら "bad interpreter" というエラーが出た」「Windowsのメモ帳やエディタで書いたスクリプトをLinuxで動かしたのに何も起きない」

こんな経験をしたことはありませんか?実はこれ、WSL2を使い始めた初心者が最初につまずくポイントのひとつです。原因は「改行コード」の違いにあります。

実行環境:Ubuntu 24.04 LTS(WSL2)・Rocky Linux 9.4 で動作確認済み

この記事では、WindowsとLinuxの改行コードの違いをわかりやすく説明し、cat -Afile コマンドで問題を特定し、dos2unix コマンドで一括修正する手順を、実際の実行例付きで解説します。

この記事のポイント

・WSL2でのスクリプトエラーの原因は改行コード(CRLF)が混入しているから
・cat -A コマンドで「^M」が表示されればCRLFが混入している証拠
・dos2unix コマンド1つでLFに一括変換できる(apt/dnfでインストール)
・VS Codeのデフォルト改行コードをLFに設定すれば再発を防げる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

WindowsとLinuxの改行コードの違いとは?

テキストファイルには「行の終わりはここです」という記号が含まれています。これを「改行コード」と言います。

問題は、WindowsとLinuxでは、この改行コードの種類が異なることです。
OS 改行コード 記号 内容
Windows CRLF \r\n CR(キャリッジリターン)+ LF(ラインフィード)の2文字
Linux / Mac LF \n LF(ラインフィード)の1文字のみ
Windowsのメモ帳や多くのエディタは、デフォルトでCRLF(\r\n)を使ってファイルを保存します。このファイルをWSL2のLinux環境で実行すると、Linuxが \r(CR)を余計な文字として読み込んでしまい、スクリプトが正常に動かないのです。

たとえば、シェルスクリプトの1行目 #!/bin/bash がWindowsで書かれた場合、Linuxからは #!/bin/bash\r と見えます。/bin/bash\r という実行ファイルは存在しないため、「bad interpreter」エラーになります。

改行コードを確認する方法

まず、ファイルにCRLFが混入しているかどうかを確認しましょう。

1. cat -A コマンドで確認する

cat -A コマンドは、通常は見えない特殊文字を画面に表示します。CR(\r)は ^M として表示されます。

# check if the file has crlf line endings (^M means crlf) cat -A test.sh

以下は、WSL2 Ubuntu上での実際の実行例です。

user@DESKTOP-LM2024:~$ cat -A test.sh #!/bin/bash^M$ echo "Hello, World!"^M$ sleep 1^M$ echo "Done."^M$

^M$ と表示されている行は、CRLF(\r\n)で終わっています。$ だけの行はLFのみで正常です。なお、同じファイルの中に ^M$ の行と $ だけの行が混在している場合は、Windows側で一部の行だけを後から編集し直したファイルによくあるパターンです。どこから改行コードが崩れたかの手がかりになります。

2. file コマンドで確認する

file コマンドを使うと、ファイルの改行コードの種類を一言で確認できます。

# ファイルの種類と改行コードを確認する file test.sh

user@DESKTOP-LM2024:~$ file test.sh test.sh: POSIX shell script, ASCII text executable, with CRLF line terminators

「with CRLF line terminators」と表示されていれば、CRLFが混入しています。変換後は「ASCII text executable」とだけ表示されます。

改行コードをLFに変換する方法

1. dos2unix をインストールする

CRLFをLFに変換するには、dos2unix コマンドが便利です。WSL2(Ubuntu)にはデフォルトで入っていないことがあるため、まずインストールします。

# Ubuntu / Debian 系(WSL2デフォルト) sudo apt install -y dos2unix # Rocky Linux / RHEL 系 sudo dnf install -y dos2unix

2. dos2unix で CRLF を LF に変換する

注意:dos2unix は元のファイルを直接上書きします。大切なファイルは事前にバックアップを取ってください。

インストールができたら、以下のコマンドでファイルを変換します。

# CRLFをLFに変換する(元ファイルを上書き) dos2unix test.sh

user@DESKTOP-LM2024:~$ dos2unix test.sh dos2unix: converting file test.sh to Unix format...

変換後に cat -A で確認すると、^M が消えているはずです。

user@DESKTOP-LM2024:~$ cat -A test.sh #!/bin/bash$ echo "Hello, World!"$ sleep 1$ echo "Done."$

^M が消えて $ だけになりました。これでスクリプトが正常に動作します。

3. sed コマンドで一発変換する(インストール不要)

社内ポリシーなどでパッケージのインストールが制限されている環境では、標準コマンドの sed だけでも同じ変換ができます。

# 行末のCR(\r)を削除する(元ファイルを上書き) sed -i 's/\r$//' test.sh

-i オプションで元ファイルを直接書き換えます。バックアップを残したい場合は sed -i.bak 's/\r$//' test.sh のように拡張子を指定すると、変換前のファイルが test.sh.bak として残ります。

4. dos2unix がない場合は tr コマンドで代替する

dos2unixsed も使えない環境では、tr コマンドで代替できます。ただし、元ファイルの直接上書きはできないため、別ファイルに出力してから置き換えます。

# CR(\r)を削除して新しいファイルに出力する tr -d '\r' < test.sh > test_fixed.sh # 内容を確認してから元ファイルを置き換える mv test_fixed.sh test.sh

再発させないための設定

ファイルを修正しても、毎回Windowsで編集するたびにCRLFが混入してしまいます。根本的に防ぐための設定を紹介します。

1. VS Code のデフォルト改行コードを LF に変更する

WSL2で作業する方の多くがVS Codeを使っているはずです。VS Codeのデフォルト改行コードをLFにすることで、新しく作成するファイルにCRLFが混入しなくなります。

・VS Codeを開き、ウィンドウ右下の「CRLF」または「LF」の表示をクリックする
・ドロップダウンで「LF」を選択する

または、設定ファイル(settings.json)に以下を追加する方法もあります。

# VS Code の settings.json に追加(デフォルト改行コードをLFに設定) { "files.eol": "\n" }

2. .gitattributes で自動管理する(Git 使用者向け)

Gitでバージョン管理している場合は、.gitattributes ファイルを作成してシェルスクリプトの改行コードをLFに固定できます。

# shell scripts and config files: always use lf (not crlf) *.sh text eol=lf *.conf text eol=lf *.yaml text eol=lf *.yml text eol=lf

この設定をリポジトリに入れておくと、チームメンバーがWindowsで作業してもCRLFの混入を防げます。

3. Gitのautocrlf設定も確認する

.gitattributes を設定していても、Windows側のGitで core.autocrlftrue のまま残っていると、チェックアウトのたびに改行コードが再びCRLFへ変換されてしまうことがあります。WSL2(Linux)側のGitでは、以下のコマンドで設定を確認・変更しておきましょう。

# 現在のautocrlf設定を確認する git config --get core.autocrlf # WSL2(Linux)側ではinputに設定するのが基本 git config --global core.autocrlf input

input に設定すると、コミット時にCRLFをLFへ変換し、チェックアウト時は変換しない動作になります。.gitattributes と組み合わせることで、改行コードの混入をより確実に防げます。

改行コードが原因と気づきにくい実務トラブル例

改行コードの問題は、シェルスクリプトの実行エラーだけでなく、次のような場面でも姿を変えて現れます。あわせて覚えておくと、原因の切り分けが早くなります。

・ExcelでCSVファイルを保存してLinuxのバッチ処理に読み込ませると、CRLFが混入したままawkやsedの正規表現が想定通りにマッチしないことがある
・SFTPクライアントの「テキストモード転送」設定が改行コードを自動変換し、バイナリのつもりで送ったファイルまで書き換えてしまうことがある
・crontabに登録したスクリプトが手動実行では動くのに、cron経由だとエラーになる場合、手動実行時にだけ改行コード修正済みの別ファイルを見ていたというケースもある

いずれも「ファイルの中身は正しいのに、目に見えない部分が原因で動かない」という点は共通しています。動作がおかしいと感じたら、まず file コマンドで改行コードを確認する癖をつけておくと、原因特定にかかる時間を大きく減らせます。

トラブルシュート

「bad interpreter: No such file or directory」が出たときの確認手順

このエラーが出たら、まず改行コードを疑ってください。以下の順序で確認します。

file スクリプト名 を実行して「CRLF」と表示されるか確認する
・「with CRLF line terminators」があれば dos2unix スクリプト名 または sed -i 's/\r$//' スクリプト名 で変換する
・変換後に chmod +x スクリプト名 で実行権限を付与する
・再度 ./スクリプト名 で実行する

改行コードを修正してもエラーが出る場合は、実行権限が付いていない可能性があります。

# 実行権限を確認する(末尾に x が付いていることを確認) ls -la test.sh # 実行権限を付与する chmod +x test.sh

「そのようなファイルやディレクトリはありません」というエラーメッセージ自体は、パスの誤りやタイプミスでもよく出ます。改行コード以外の原因も考えられるため、file コマンドでCRLFの有無を先に確認してから対処すると、原因を見誤らずに済みます。

本記事のまとめ

WSL2での改行コード問題への対処法をまとめます。
やりたいこと コマンド
改行コードを目視で確認する cat -A ファイル名
改行コードの種類を確認する file ファイル名
CRLFからLFへ変換する dos2unix ファイル名
インストール不要でCRLFからLFへ変換する sed -i 's/\r$//' ファイル名
LFからCRLFへ変換する(逆変換) unix2dos ファイル名
dos2unix なしでCRLFを除去する tr -d '\r' < 入力 > 出力
dos2unix をインストールする(Ubuntu) sudo apt install dos2unix
dos2unix をインストールする(RHEL系) sudo dnf install dos2unix
Gitのautocrlf設定を確認する git config --get core.autocrlf
WSL2でWindowsとLinuxを行き来する開発環境では、改行コードの違いは避けて通れません。dos2unixsed を使いこなして、スクリプトのトラブルをすばやく解決できるようにしておきましょう。

Linuxのシェルスクリプトやサーバー管理をさらに深く学びたい方は、ぜひ以下の関連記事も参照してください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、
無料の「Linuxサーバー構築入門マニュアル(図解60ページ)」をプレゼントしています。
WSL2とLinuxの連携をさらに深め、実務で使えるスキルを身につけたい方は、ぜひ受け取ってみてください。
無料マニュアルを受け取る >>

関連記事(Linux実務スキル)

改行コードの問題を解決したら、次はLinux実務スキルの各テーマを深掘りしていきましょう。

trapコマンドでbashスクリプトのシグナルを捕捉・処理する方法|一時ファイル削除やエラー終了処理の実践例も【シェルスクリプト】
fail2banコマンドでブルートフォース攻撃を自動ブロックする方法|SSHの不正アクセス対策とトラブルシュートも【セキュリティ】
nmcliコマンドでネットワーク接続を設定する方法|静的IP・DHCP・接続追加・削除の手順も【サーバー構築】
straceコマンドでプロセスのシステムコールを追跡する方法|Permission deniedの原因特定やデバッグも【トラブルシューティング】
nmapコマンドでポートスキャン・ネットワーク診断を行う方法|-sSや-Aの使い方とセキュリティ活用も【ネットワーク】
lsblkコマンドでブロックデバイスを一覧表示する方法|ディスク構成やパーティション確認も【ディスク操作】
watchコマンドで定期的にコマンドを繰り返し実行する方法|変化の検出やログ監視にも【Linux Tips】

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。