Windows找不到subprocess.call()函数中的文件。

136

我遇到了以下错误:

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

我的代码是:

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

我使用的是Windows 7 64位操作系统,Python版本是最新稳定版的3.x。

有什么想法吗?

谢谢。


这是可执行文件是什么? - SilentGhost
2
并且它在PATH上可用。 - Sri
你能否从命令行运行它? - SilentGhost
@SilentGhost:是的,我可以从命令行运行它。在Python中,os.sys(“…”)调用也可以工作。 - Sri
如果路径中有空格,是否加上引号?当然,你已经正确转义了反斜杠,或者使用了正斜杠,对吧? - Ryan Ginstrom
显示剩余2条评论
7个回答

220

如果命令是一个shell内置命令,在调用时需要添加shell=True选项。

例如,对于dir命令,您应该键入:

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

引用自文档:

在 Windows 系统下,只有当你要执行的命令是内置于 shell 中(例如 dircopy)时,才需要指定 shell=True。运行批处理文件或基于控制台的可执行程序不需要使用 shell=True


19
这是因为在*nix中没有名为dir.exe的可执行文件,而有一个/bin/lsdir由_CMD.EXE_实现,就像cd由_bash_实现一样。 - Apalala
1
这是强烈不建议的。https://docs.python.org/2/library/subprocess.html#frequently-used-arguments - nu everest
12
只有当“命令字符串由外部输入构建”时。 - Jirka
另一种更安全的方法(适用于外部输入)是从os.environ获取PATH并手动搜索它。 - asmeurer

49
在Windows系统上,我认为subprocess模块不会查找PATH路径,除非你传递shell=True参数,因为它在背后使用CreateProcess()。然而,如果你正在传递可能来自程序外部的参数,shell=True可能会带来安全风险。为了让subprocess仍能够找到正确的可执行文件,你可以使用shutil.which。假设你的PATH路径中的可执行文件名为frob
subprocess.call([shutil.which('frob'), arg1, arg2])

(这适用于 Python 3.3 及以上版本。)


4
有Python 2的选项吗? - Naramsim
@Naramsim 请尝试使用 from distutils.spawn import find_executable as which。这行代码是从 pre-commit 的钩子脚本中复制的。 - Allan Chain
这不正确。系统即使没有 shell=True 也会检查 PATH,但 shell 内置命令(如 cddir)不在 PATH 上,因为它们根本不是可执行文件。这就是内置于 shell 中的含义;该命令由 shell 自身理解和执行,并不存在作为单独二进制文件的存在。 - tripleee

27
在Windows上,您需要通过cmd.exe调用。正如Apalala所提到的,Windows命令是在cmd.exe中实现的,而不是作为单独的可执行文件。
例如.
subprocess.call(['cmd', '/c', 'dir'])

/c指示cmd运行紧随其后的命令

这比使用shell=True更安全,因为shell=True存在shell注入的风险。


我该如何保持屏幕打开? - Moondra
2
@Moondra,如果我理解正确的话,请尝试使用/k而不是/c。在命令行中输入cmd /?以获取详细信息。 - User5910
这个答案帮助了我解决在Windows 10上使用PowerShell时出现的WinError 5权限被拒绝的问题。 - enjoi4life411
这只是重新实现 shell=True 的绕路方式。 - tripleee

3
如果你正在使用PowerShell,则可以使用以下代码:subprocess.call(['powershell','-command','dir'])。 PowerShell支持大部分POSIX命令。

“dir”不是POSIX命令。 - tripleee

2

在经过一番思考之后,我发现在64位机器上运行32位Python时,运行位于C:\Windows\System32\的文件可能会出现潜在问题,这是由于Windows试图智能地处理进程,并将调用重定向到C:\Windows\SysWOW64。

我在这里找到了一个解决方法的示例:http://code.activestate.com/recipes/578035-disable-file-system-redirector/


0

在调用 PHP 时,我遇到了同样的问题。原因是 PHP 没有在 PATH 中,所以找不到 PHP 命令。但 PowerShell 发现它存在于当前位置,并建议如果我信任此命令,则替换 'PHP' 为 '.\PHP'。然后它运行良好。


0

引用文档中的内容:

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

所以:在 Python 3.5 及以上版本中,不再使用 subprocess.call,而是使用 subprocess.run。


这是一条本身不错的建议,但对于解决这里实际问题没有任何帮助。 - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接