at backyard

Color my life with the chaos of trouble.

Pythonのsubprocess.Popenでファイルを開こうとすると【[WinError 2] 指定されたファイルが見つかりません】

Windows環境でsubprocess.Popenでファイルを開こうとすると【[WinError 2] 指定されたファイルが見つかりません】というエラーがでる

MacWindowsどちらにも対応したアプリを書いていて、とある処理でPythonのsubprocess.Popenを使って指定したファイルを開く処理を書いた際に躓いたこととその解決法に関するメモとなる。

import subprocess
import os
from os import path
・
・
・
file_path = path.join(os.getcwd(), 'foo.txt')

if os_name == "windows":
  subprocess.Popen(["start", file_path])
elif os_name == "mac":
  subprocess.Popen(["start", file_path])
・
・
・

実際のコードとは異なるが、だいたいこんな感じの内容のコードを書いた。

このコードを手元のMacで実行すると、対応するファイルで foo.txt を開いてくれる。

windowsの場合、open ではなく start を使うということだったので、このように記述してみたが、実際にWindows環境で動かしてみると、

[WinError 2] 指定されたファイルが見つかりません

というエラーが出てしまう。

どうやらsubprocess.Popen の引数に shell=True を与える必要があるようだった。

というわけで、下記のようにwindowsの場合のみ shell=True を与えることでWindowsMacどちらの環境でも対応するアプリでファイルが開かれるようになった。

import subprocess
import os
from os import path
・
・
・
file_path = path.join(os.getcwd(), 'foo.txt')

if os_name == "windows":
  subprocess.Popen(["start", file_path], shell=True)
elif os_name == "mac":
  subprocess.Popen(["start", file_path])
・
・
・

Pythonのsubprocess.Popenの公式ドキュメント

ちなみにこの内容に関する公式ドキュメントは下記となる。

docs.python.org

こちらのページにWindows環境で shell=True を動かす際のことについても記載がある。

Windows で shell=True とすると、COMSPEC 環境変数がデフォルトシェルを指定します。Windows で shell=True を指定する必要があるのは、実行したいコマンドがシェルに組み込みの場合だけです (例えば dir や copy)。バッチファイルやコンソールベースの実行ファイルを実行するために shell=True は必要ありません。

他にもセキュリティ的に考慮すべきことなども書かれているので、そちらについても読んでおいたほうが良いだろう。