事象
Windows機から転送したスクリプトをLinux機で実行した際に
$ ./test.sh bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory
とエラーとなる。
コマンド実行環境
- Debian GNU/Linux 9 (stretch)
原因と対策
該当スクリプトは一行目に以下のように記載、末尾に改行が入っている。
#!/bin/bash⏎
原因は改行コードを正しく認識できていない。
スクリプトをfileコマンドで確認すると
$ file test.sh test.sh: Bourne-Again shell script, Non-ISO extended-ASCII text executable, with CRLF line terminators
ASCII形式かつ改行コードがCR+LFで入っている。当ファイルをWindowsで作成したことが理由。
ちなみにDebian機でシェルスクリプトを作成するとUTF-8かつ改行コードについては記述なし。実体はLF形式。
$ vi hoge.sh $ file hoge.sh hoge.sh: Bourne-Again shell script, UTF-8 Unicode text executable
よってnkfコマンドの-L[uwm]
オプションを利用して
- Lu : unix (LF)
- Lw : windows (CRLF)
- Lm : mac (CR)
改行キーを変換します。
$ cat test.sh | nkf -Lu > test2.sh $ file test2.sh test2.sh: Bourne-Again shell script, UTF-8 Unicode text executable
test2.shに関しては実行権限を付与してあげれば実行できるようになります。
以下は、おまけです。
おまけ
改行コードのみを変換しましたが、ASCIIからUTF-8に変更がされていました。
では同じくUTF-8へ変換する-w
オプションを利用すれば改行も変換されるのでしょうか?
結論から言うと変換はされません。
$ cat test.sh | nkf -w > test3.sh $ file test3.sh test3.sh: Bourne-Again shell script, UTF-8 Unicode text executable, with CRLF line terminators
文字コードは変換されましたが改行コードは変換されません。
よって実行もできません。
$ ./test3.sh bash: ./test3.sh: /bin/bash^M: bad interpreter: No such file or directory
-Lu
は-w
より強力というのは頭の片隅に入れておくとどこかで役立つかもしれません。
確かにCygwinでも
$ ipconfig | head Windows IP ▒\▒▒ ...
同じように機能します。
$ ipconfig | head -n 2 | nkf -w Windows IP 構成 ... $ ipconfig | nkf -Lu Windows IP 構成 ...
ご参考になれば幸いです。