为啥 Python 不能通过子进程执行 java.exe?

Posted

技术标签:

【中文标题】为啥 Python 不能通过子进程执行 java.exe?【英文标题】:Why can't Python execute java.exe via subprocess?为什么 Python 不能通过子进程执行 java.exe? 【发布时间】:2012-05-19 23:05:55 【问题描述】:

在将 Java 从 1.6 升级到 1.7 x64(在 Windows 7 上)后,我突然无法再通过 Python 2.7 的 subprocess 模块启动 java.exe。以下脚本曾经可以正常工作:

import subprocess
subprocess.check_call([r"C:\Windows\system32\java.exe"])

现在它像这样失败了:

Traceback (most recent call last):
  File ".\tst.py", line 2, in <module>
    subprocess.check_call([r"C:\Windows\system32\java.exe"])
  File "C:\Python27\lib\subprocess.py", line 506, in check_call
    retcode = call(*popenargs, **kwargs)
  File "C:\Python27\lib\subprocess.py", line 493, in call
    return Popen(*popenargs, **kwargs).wait()
  File "C:\Python27\lib\subprocess.py", line 679, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 896, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

我还确认C:\Windows\system32\java.exe确实存在,是一个应用程序,并且可以从命令shell执行。

这里出了什么问题?

编辑: 我发现我可以从 Python 启动 C:\Program Files\Java\jre7\bin\java.exe,所以 C:\Windows\system32\java.exe 一定是一些奇怪的伪快捷方式,尽管从技术上讲是一个 Windows 应用程序。 1.7 版肯定搞砸了,因为我刚刚确认 1.6 版没问题。

【问题讨论】:

你确定不是链接吗? @Marcin 根据文件属性,文件类型为Application (.exe) 如果您可以进行更多调查,您的编辑将是一个很好的答案。如果您无法进行更多调查,请考虑将其添加为答案。 @Marcin 将向 Java 开发人员提交反馈,希望他们能回复我。 运行 fsutil,它不是硬链接 【参考方案1】:

假设“C:\Windows\System32”中有一个 java.exe 并不是一个特别安全的假设。即使假设系统上有“C:\Windows\System32”也不安全:Windows 可以驻留在计算机上的任何固定驱动器上。

但即使有“C:\Windows\System32\java.exe”,这对于 Win64 下的 32 位进程也可能不可见。 Windows 在这里以向后兼容的名义做了一些有趣的事情,你可能想看看http://en.wikipedia.org/wiki/WoW64。

找到您正在寻找的 Java 版本(可能有很多)可能是一项吃力不讨好的任务。如果您不特别关心您找到的哪个 Java,请尝试使用 JAVA_HOME 环境变量。它并不总是存在,但如果存在,你就完成了,它可能是查找 JVM 的最便携的方式。如果它不存在,那么设置它就不会出错,而且许多 Java 应用程序都可以使用该变量。

然后,Java 只是可能在 PATH 上,在这种情况下删除子进程调用中除了“java”之外的所有东西都可以解决问题。试一试也无妨。

【讨论】:

C:\Windows\system32\java.exe 与我相关的原因是我通常通过PATH 找到 java.exe,我不直接依赖该可执行路径.但是你很可能对魔兽世界64有所了解,我会调查的,谢谢。 你在做某事。使用 32 位 Python 执行以下命令时会打印 False,但对于 64 位 Python 执行以下操作时会打印 Truepython.exe -c "import os.path; print os.path.exists(r'C:\windows\system32\java.exe')"。显然 64 位 Windows 上的 32 位应用程序从 C:\Windows\System32 重定向到 C:\Windows\SysWOW64,其中没有 java.exe。 为什么这不是 SO 历史上投票率最高的答案之一? 我也遇到了这个错误。对我来说,直接使用路径“C:\Program Files\Java\jre7\bin\java.exe”有效(64 位,1.7.0_67-b01)。即使我使用 subprocess.check_output(...) 发出合法命令,仅使用“java”(来自 PATH)也不会返回任何输出【参考方案2】:

您可能还想检查 PATH 环境变量是否在 jre 的 bin 路径周围有引号“”。 Python 似乎不喜欢它们:

    C:\bin>set PATH=C:\Python27;c:\Program Files\Java\jdk1.6.0_35\bin

    C:\bin>python -c "import subprocess; subprocess.Popen(['java', '-version'], stderr=subprocess.PIPE)"

    C:\bin>set PATH=C:\Python27;"c:\Program Files\Java\jdk1.6.0_35\bin"

    C:\bin>python -c "import subprocess; subprocess.Popen(['java', '-version'], stderr=subprocess.PIPE)"
    Traceback (most recent call last):
    [...]
    WindowsError: [Error 2] The system cannot find the file specified

    C:\bin>

【讨论】:

以上是关于为啥 Python 不能通过子进程执行 java.exe?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Python 子进程“继承”父进程的线程?

当子进程仍然打开时,为啥 Java 进程会从 Gradle 挂起?

为啥 Java 创建的两个子进程行为不同?

为啥 Python 子进程中的 ln 在正常命令行成功时失败?

JAVA中如何执行DOS命令

python多进程和多线程