コマンドラインやCGIなどのPerlプログラムでbad interpreterというエラーが出て実行できない時がある。
$ cat crlf.pl
#!/usr/bin/perl use strict; use warnings; print "Hello\n";
$ ./crlf.pl
-bash: ./crlf.pl: /usr/bin/perl^M: bad interpreter: No such file or directory
これは大抵改行コードの問題。
Perlインタープリターに明示的にファイル名を与えると特に問題がない。
$ perl crlf.pl
Hello
なので、ネット上ではPerlインタープリターに明示的に渡せないCGIで困っているケースが散見される。
"./script" などと「直接実行」した場合、まず実行しているOS環境(Linuxとか*BSDとか)が、それがスクリプトファイルなのか直接実行形式ファイルなのかを判別するが、前者の場合は1行目のshebang行が頼りになる。
ただ、Linuxなどの環境で改行コードとしてCR+LFを想定していない場合、shebang行がエディタでの見かけ上 #!/usr/bin/perl などとなっていても、それがCR+LF改行コードの場合には、LFが改行コードのOSにとってshebang行は
#!/usr/bin/perl<CR>
となってしまい「"/usr/bin/perl<CR>" なんて存在しない」と言われることになる。これが bad interpreter の意味。
解決方法はエディタで改行コードをLFに変更すること。
一番上の実行例では"^M"としてCRが可視化されているから分かりやすいものの、可視化されない環境もある。
ネットでは「shebang行を #!/usr/bin/perl から #!/usr/bin/perl -w に変更すれば動く」という「解決法」も紹介されているが、たまたまperlが -<CR> というオプションを無視するから上手くいくだけで、これはバッドノウハウでしかない。モダンなPerlプログラムはshebang行の -w で warnings を有効にするのではなく、warnings プラグマで有効にする (use warnings; する) ほうが一般的。
「改行コードをLFに変換したらWindowsのメモ帳で改行が無くなった」というクレームに対しては、HTMLならまだしも「通常UNIX系OSで実行されるスクリプトファイルの改行コードはLFなのだから対応するエディタを導入してください」という回答が最適だろう。そういったエディタはフリーソフトで大量に存在する。