Raspberry Pi で、“FileNotFoundError: [Errno 2] No such file or directory: ” のエラーが出たときの対処方法についてまとめておきます。
以下の環境で現象を確認しています。
・ Raspberry Pi (bullseye)
・ Windows パソコン
背景
日頃、Windows パソコンから、ローカルネットワークを介して Raspberry Pi にアクセスし、Webアプリの作成などをしています。
Raspberry Pi 側で Webサーバー(http.server)を起動し、Windows パソコンから、Raspberry Pi の cgi のフォルダ内にある Python のスクリプトにアクセスしたところ、Python のスクリプトがあるにもかかわらず、冒頭のエラーが 表示されました。
対処方法をまとめておくことにします。
現象 ~ ファイルがあるのに FileNotFoundError が出る
エラーが出る手順は、以下の通りです。
① Windows パソコンと Raspberry Pi を起動します。両方とも、ローカルネットワークに接続する設定にしてあります。
② Windows パソコンからリモートデスクトップを介して Raspberry Pi にログインし、Python のウェブサーバー用のフォルダを作成します。
例: /home/pi/web_server1/
③ ②のフォルダ内にさらに CGI 用のフォルダを作成し、CGI 用のスクリプト script1.py をテキストファイルで作成し、実行権限を与えておきます。
例:
cd /home/pi/web_server1/cgi-bin/
chmod 755 script1.py
④ Python の Webサーバーを起動させます。
例:
python3 -m http.server 8000 -cgi
⑤ Webサーバーの起動後、ローカルネットワーク内の Windows パソコンの Microsoft Edge ブラウザから、Raspberry Pi サーバーにアクセスします。
例:
ブラウザの URL に以下を入力する。
192.168.X.X:8000/cgi-bin/script1.py
→ 以下のエラーが、④で起動中のRaspberry Pi のターミナルに表示される。。
・ エラー表示 ”FileNotFoundError: [Errno 2] No such file or directory: ‘/home/pi/web_server1/cgi-bin/script1.py’
・ Raspberry Pi 上で script1.py を確認すると、No such file or directory と表示されているにもかかわらず、ファイルは存在している。
対処方法
① ターミナルで、cgi が入っているフォルダに移動します。
例: cd /home/pi/web_server1/cgi-bin
② ファイルを確認します。なお、以下の事例では、Python の CGI 用のスクリプトのファイル名を script1.py として記載します。ファイル名やフォルダの場所が異なる場合は、読み替えてください。
例: ls -al
念のため、Python のスクリプトの実行権限を確認してください。
script1.py の表示が緑色になっていれば、Webサーバーのアプリから実行が可能な権限が与えられています。
白色である場合は、下記を例に実行権限を与えてください。
例: chmod 755 script1.py
→ ls -al で、緑色の表示に切り替わったら、OK です。
Raspberry Pi にログインしているときのユーザー名は、デフォルトで pi 等になっていると思います。
一方、Webサーバーのユーザー名は pi ではないため、pi 以外のユーザーにも読み取りと実行の権限 5 (= 4+0+1 ) を与えておきます。
③ Webサーバーのプログラムを起動した状態で、ネットワーク内の他の PC (Windows パソコン)などから、アクセスしてみてください。
→ FileNotFoundError が出る場合、以下を続けてください。
④ 以下のファイルコマンドを実行し、テキストファイルがどういうフォーマットで書かれているか、確認します。
例: file script1.py
→ 以下のような出力が出ると思います。
例1: script1.py: Python script ASCII text executable, with CRLF, LF line terminators
例2: script1.py: Python script, UTF-8 Unicode text executable, with CRLF line terminators
※ 日本語を扱うには、UTF-8 Unicode のフォーマットにすると問題が少ないようです。
※ また、改行(ターミネーター)の文字について、Windows では CRLF の2文字が使われています。一方、Linux (Unix) では LF の1文字が使われます。上記の例1、例2では、ターミネーターに CRLF が使われている旨の表示となっています。
⑤ そこで以下、CRLF を LF に置き換え、UTF-8 のフォーマットに変換することにします。
以下のコマンドを実行し、テキストファイルのフォーマットを Unix 形式に変換します。以下のコマンドを実行すると、script1.py はフォーマットを Unix 形式にしたのち、上書き保存します。オリジナルのファイルを残しておきたい場合は、事前にバックアップを取っておいてください。
例: dos2unix -o script1.py
→ ファイル script1.py が Unix 形式に書き換えられます。
⑥ もう一度、file コマンドを実行し、ファイルフォーマットを確認します。
例: file script1.py
→ 以下の表示となると思います。
表示: script1.py: Python script, UTF-8 Unicode text executable
※ 実行可能な UTF-8 形式で書かれた Python スクリプトとなっている、といった旨の表示となりました。
⑦ ⑥の確認後、Windows パソコンから再度、Raspberry Pi のサーバーにアクセスしたところ、下記の表示となりました。
表示
192.168.X.X — […] CGI script exit code 127
192.168.X.X — […] “GET /cgi-bin/scrpt1.py HTTP/1.1” 200 –
→ エラー表示が解消され、Python のスクリプトが正常に実行できました!
まとめ
ファイルが存在しているのにファイルがないというエラーが出たときの対処方法についてまとめました。
MS-DOS のファイルを Unix に変換するツール dos2unix が標準で入っているので、これを使えばよいということでした。
なお、以前、同様な現象として、”/usr/bin/env:…” といったエラーが出たことがありましたが、原因としては同じようです。最近の Bullseye ではエラー表示が変わったのでしょうか。
また、”No such file or directory” という表現が不正確なので混乱します。この表現から dos2unix は思いつきません。”cannot access such file or directory” といった表現であれば、原因や対策をイメージしやすいのですけれども。。
関連リンク
・ Raspberry Pi でローカルWebサーバー 【Python 活用】
・ “/usr/bin/env: ‘python\r’: そのようなファイルやディレクトリはありません”と表示されたとき 【Raspberry Pi】
・ エラーコードのまとめ 【Webサーバー】