从 mingw 运行的 Python 子进程无法找到二进制文件



我有一组python模块,我想在linux和MinGW(Windows)上工作。

虽然子进程在Linux上工作正常,但在Windows subprocess.call/Popen上不断抛出错误,说找不到所需的二进制文件。

例如,我经常使用Xilinx的Vivado(EDA工具)。虽然只需在 mingw 提示符中键入"vivado"就可以正常工作并且启动了 vivado,但如果我尝试通过子进程调用 vivado,我会收到一条错误消息,说找不到该文件。

我的 mingw 环境路径变量包含:/c/Xilinx/Vivado/2015.2/bin这是找到 vivado 二进制文件的地方。如果我启动 python 并执行此操作,

print os.environ['PATH']

我看到它包含:C:\Xilinx\Vivado\2015.2\bin;

所以我想python在启动时执行了适当的翻译。

另外,如果我尝试从python的子进程启动vivado而不是vivado.bat(文件包含在与二进制文件相同的目录中),则一切正常并且二进制文件已启动。

vivado 二进制文件具有执行权限...

所以我的问题是。这个问题是已知的吗?解决它最干净的方法是什么?

谢谢!

不确定这是否准确回答了 OP,但我认为它是高度相关的: 考虑这个例子,其中可执行路径是Windows风格的,带有反斜杠:

#!/usr/bin/env python3
import sys, os
import subprocess
NOTEPADPATH = r"C:WINDOWSsystem32notepad.exe"
print("NOTEPADPATH is {}".format(NOTEPADPATH))
proc_notepad = subprocess.Popen([NOTEPADPATH], shell=False)

如果我在 MSYS2 外壳中运行它,它会失败:

$ python3 test.py
NOTEPADPATH is C:WINDOWSsystem32notepad.exe
Traceback (most recent call last):
File "test4.py", line 11, in <module>
proc_notepad = subprocess.Popen([NOTEPADPATH], shell=False)
File "/usr/lib/python3.7/subprocess.py", line 775, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.7/subprocess.py", line 1522, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'C:\WINDOWS\system32\notepad.exe': 'C:\WINDOWS\system32\notepad.exe'

如果我在 Anaconda 3 shell Python3(显然是针对 Windows 本机编译)中运行它,它会成功(记事本已启动):

(base) C:msys64tmp>python test.py
NOTEPADPATH is C:WINDOWSsystem32notepad.exe

如果我们现在更改可执行路径,那么它使用正斜杠作为路径分隔符,而不是反斜杠:

#!/usr/bin/env python3
import sys, os
import subprocess
NOTEPADPATH = r"C:/WINDOWS/system32/notepad.exe"
print("NOTEPADPATH is {}".format(NOTEPADPATH))
proc_notepad = subprocess.Popen([NOTEPADPATH], shell=False)

。然后它在启动记事本的 MSYS2 中都成功:

$ python3 test.py
NOTEPADPATH is C:/WINDOWS/system32/notepad.exe

。在 Anaconda 3 shell Python3 中:

(base) C:msys64tmp>python test.py
NOTEPADPATH is C:/WINDOWS/system32/notepad.exe

根据我的经验,Python 似乎找不到具有.cmd扩展名的可执行文件。对于 MinGW 版本和标准 Windows 软件包,尽管.cmd列在PATHEXT环境变量中。我的解决方案是将扩展添加到命令中:

# executable with .exe extension
>>> subprocess.run(("node", "--version"), check=True)
v18.15.0
CompletedProcess(args=('node', '--version'), returncode=0)
# executable with .cmd extension
>>> subprocess.run(("npm", "--version"), check=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:EnvironmentPythonLibsubprocess.py", line 548, in run
with Popen(*popenargs, **kwargs) as process:
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:EnvironmentPythonLibsubprocess.py", line 1024, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "C:EnvironmentPythonLibsubprocess.py", line 1493, in _execute_child
hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [WinError 2] The system cannot find the file specified
>>> subprocess.run(("npm.cmd", "--version"), check=True)
9.5.0
CompletedProcess(args=('npm.cmd', '--version'), returncode=0)

因此,如果您正在构建跨平台应用程序,则需要在执行之前进行操作系统检查并附加扩展。

command = "npm"
if sys.platform == "win32":
command += ".cmd"

最新更新