第25回補足 「/usr/bin/php/^M: 誤ったインタプリタです」の対策

PHPやPythonプログラムを実行すると「/usr/bin/php/^M: 誤ったインタプリタです: …」というようなエラーになる場合は、改行コードの問題です。エディタの設定を変更する必要がありますので、その方法を説明します。

コメントいただいた内容

第25回のGPIO制御説明で、PHPのプログラムを実行してもエラーになる旨報告いただきました。すみません、ここまで配慮するのを忘れていました。

問題の内容は、PHPやPythonのプログラムを実行すると、

-bash: ./test.php: /usr/bin/php^M: 誤ったインタプリタです: そのようなファイルやディレクトリはありません

というようなエラーが発生する、というものです。これは改行コードが「LF」になっていないために発生します。

最初にWindows版、Macintosh版のメジャーなエディタアプリの設定方法を説明した後、最後にエラーが発生する原因を説明します。

 

Windows版のエディタ設定方法

Windows版のエディタは、メジャーなところですと、TeraPadやサクラエディタあたりでしょうか。この2つのエディタの設定方法を説明します。

Windows版のエディタの場合、デフォルトの改行コードの設定はほとんどのエディタアプリで「CR+LF」になっています。エディタの設定を特に変更しないで保存すると、CR+LFの改行コードとなり、Raspberry PiのPHPやPythonの実行時にエラーになります。

それでは、最初にTeraPadの設定方法です。

TeraPadを立ち上げると、文字コードはShift-JIS、改行コードはCR+LFになっています。

Terapad defult

変更する場合は、「ファイル(F)」メニューから「文字/改行コード指定保存(K)…」を選択します。

Win tp lf setting 1

以下のような設定ダイアログが表示されます。

Terapad settings 1

文字コードをUTF-8N、改行コードをLFに変更してOKボタンをクリックします。文字コードは「UTF-8」がありますが、こちらはBOMありですので、BOMなしの「UTF8-N」を選択するようにします。

OKボタンをクリックすると、この設定を保存するダイアログが表示されますので、「UTF8N-LF」などのファイル名で保存します。

Trapad settings 2

エディタに戻りますので、先ほどの文字コードと改行コードの設定表示を確認します。

Terapad modified

次にサクラエディタのケースです。サクラエディタもTeraPadと同様、エディタウインドウの下の方に、現在の文字コードと改行コードの設定が表示されています。

Win sakura lf default

サクラエディタの場合は、ファイルを保存するときに指定しますので、一度ファイルメニューから「名前をつけて保存」を選択します。保存ダイアログが表示されます。

Win sakura lf setting 1

文字コードをUTF-8、改行コードをLFに変更します。なお、文字コード選択のとなりに「CP」「BOM」というチェックボックスがありますが、これはOFFにしておきます。

Win sakura lf setting 2

保存するとエディタウインドウの文字コードと改行コードの設定表示が変わっていますので確認します。

Win sakura lf setting 3

他のエディタ(秀丸など)の場合でも、同様のメニューがありますので探してみてください。

 

Mac版のエディタ設定方法

Macの場合はメジャーなエディタはTextWranglerでしょうか。Text Wranglerの場合は説明するまでもなさそうですが、簡単に変更できます。

エディタウィンドウでは、下の方に文字コードの改行コードの設定があります。

Mac tw lf confirm

この設定はクリックして変更することができますので、それぞれUTF-8、LFに変更します。

Mac tw lf setting

Macの場合は他のエディタでも、文字コードと改行コードが表示されていれば、そこをクリックすると変更できるものが多いですので、同様に変更してみてください。

 

エラーの原因

このエラーが発生する原因を簡単に説明しておきます。

改行コードはMacintosh/UNIX/Linux系とWindowsで異なっています。まず改行を表すコードは以下のものがあります。

記号 意味 16進コード
CR Carriage Return
先頭に戻る
0x0d
LF Line Feed
1行送り
0x0a

改行する場合、どう表現するかですが、「印字位置を行の先頭に戻して、1行次に進む」と考えるのが「CR+LF」です。一方で、「1行次に進めば印字位置は先頭にリセットされる」と考えるのが「LF」です。どちらが正しいというわけでもないと思いますが、いろいろと歴史があるようで現在のようにOS毎に改行コードが異なっているようです。(歴史についてはWikipediaに詳しく説明されています)

まず、以下のようなファイルを改行コードがCR+LFで作成します。

<?php
    echo "Hello, world!";
?>

これを以下のように実行するとエラーになりません。

pi@raspberrypi ~ $ php test.php

これは、PHPインタープリタが、改行コードをどのタイプでも扱えるためです。

次に、以下のようなファイルを改行コードがCR+LFで作成します。

#!/usr/bin/php
<?php
    echo "Hello, world!";
?>

このファイルに実行権をつけて(chmod +xでしたよね)、「./test.php」で実行すると、今度はエラーになります。

先ほどのケースでは、test.phpをPHPインタープリタが処理していましたが、このケースでは、シェル(覚えてますか?)、具体的にはbashが処理することになります。上のファイルは1行目は16進数ではどうなっているかというと、

Lf

こんな感じになっています。bashはこのファイルを実行するとき、Linux上では改行コードは「LF」(0x0a)ですので、1行目は「LF」の一つ前の文字まで取り出します。ファイルの改行コードが「CR+LF」の場合、つまり16進コードでいうと「0x0d + 0x0a」の場合、LF(0x0a)の一つ前の文字まで取り出すと、

#!/usr/bin/php[CR]

という文字列になってしまいます。[CR]は実際には16進数で0x0dです。bashはこのコマンド、つまり「php」ではなく「php[CR]」というコマンドを探しに行きますが、当然このようなコマンドはありませんのでファイルが見つからないエラーとなります。

« »