Windows 在 subprocess.call() 上找不到文件

Posted

技术标签:

【中文标题】Windows 在 subprocess.call() 上找不到文件【英文标题】:Windows can't find the file on subprocess.call() 【发布时间】:2011-03-02 14:37:54 【问题描述】:

我收到以下错误:

WindowsError: [Error 2] The system cannot find the file specified

我的代码是:

subprocess.call(["<<executable file found in PATH>>"])

Windows 7、64 位。 Python 3.x 最新、稳定。

有什么想法吗?

谢谢,

【问题讨论】:

这个可执行文件是什么? android SDK 的“android”可执行部分 并且 is 在 PATH 上可用 可以从命令行运行吗? 我想要完成的事情的一点背景。这适用于 Opendevice - 一个将 html5 应用程序转换为特定于设备的应用程序的开源项目。我正在尝试将bitbucket.org/srirangan/opendevice/src/tip/tools/net/srirangan/… 中的 os.system() 替换为 subprocess.call() 【参考方案1】:

当命令是内置的 shell 时,在调用中添加 shell=True

例如对于dir,您可以输入:

import subprocess
subprocess.call('dir', shell=True)

引用documentation:

您需要在 Windows 上指定 shell=True 的唯一情况是当您希望执行的命令内置到 shell 中时(例如 dircopy)。您不需要shell=True 来运行批处理文件或基于控制台的可执行文件。

【讨论】:

这是因为在 *nix 中没有名为 dir.exe 的可执行文件,而有一个 /bin/lsdirCMD.EXE 实现,就像cdbash 实现。 强烈建议不要这样做。 docs.python.org/2/library/… @nueverest 仅当命令字符串是从外部输入构造的 另一种选择(对于外部输入更安全)是从os.environ 获取PATH 并手动搜索。【参考方案2】:

在 Windows 上,我相信 subprocess module doesn't look in the PATH unless you pass shell=True,因为它在幕后使用 CreateProcess()。但是,如果您传递的参数可能来自程序外部,shell=True 可能会带来安全风险。要使subprocess 仍然能够找到正确的可执行文件,您可以使用shutil.which。假设您的PATH 中的可执行文件名为frob

subprocess.call([shutil.which('frob'), arg1, arg2])

(这适用于 Python 3.3 及更高版本。)

【讨论】:

任何 python 2 选项? @Naramsim 试试from distutils.spawn import find_executable as which。此行是从 pre-commit 的钩子脚本中复制的。【参考方案3】:

在 Windows 上,您必须通过 cmd.exe 调用。正如 Apalala 所说,Windows 命令是在 cmd.exe 中实现的,而不是作为单独的可执行文件。

例如

subprocess.call(['cmd', '/c', 'dir'])

/c 告诉 cmd 运行以下命令

这比使用 shell=True 更安全,后者允许 shell 注入。

【讨论】:

如何保持屏幕打开? @Moondra,如果我理解正确,请尝试使用/k 而不是/c。在命令行输入cmd /?了解详情。【参考方案4】:

如果您使用的是 powershell,那么其中将是 subprocess.call(['powershell','-command','dir'])。 Powershell 支持大部分 POSIX 命令

【讨论】:

【参考方案5】:

经过一番摸索,我发现在 64 位机器上运行 32 位版本的 python 时运行位于 C:\Windows\System32\ 中的文件是一个潜在问题,因为 Windows 试图超越进程,并将对 C:\Windows\System32 的调用重定向到 C:\Windows\SysWOW64。

我在这里找到了如何解决此问题的示例: http://code.activestate.com/recipes/578035-disable-file-system-redirector/

【讨论】:

【参考方案6】:

引用文档:

“在 Python 3.5 之前,这三个函数构成了用于子进程的高级 API。现在您可以在许多情况下使用 run(),但是很多现有代码都会调用这些函数。”

SO:在 Python 3.5 及更高版本中使用 subprocess.run 代替 subprocess.call

【讨论】:

这是一个很好的建议本身,但没有解决这里的实际问题。【参考方案7】:

我在调用 php 时遇到了同样的问题。原因是 PHP 不在 PATH 中,因此找不到命令 PHP。但是 PowerShell 发现它确实存在于当前位置,如果我相信这个命令,它建议用 '.\PHP' 替换 'PHP'。然后它运行良好。

【讨论】:

以上是关于Windows 在 subprocess.call() 上找不到文件的主要内容,如果未能解决你的问题,请参考以下文章

Python subprocess.call 打不开 Notepad.exe?

subprocess.call 使用

是否有 subprocess.call 的安静版本?

在 Python 中使用 subprocess.call 播放音频

subprocess.call 路径问题,如何解决?

如何防止subprocess.call打印返回代码?