【问题标题】:Runtime.getRuntime().exec does not find the default python versionRuntime.getRuntime().exec 没有找到默认的python版本
【发布时间】:2020-04-01 09:38:46
【问题描述】:

我想使用Runtime.getRuntime().exec 执行一个简单的python 脚本Runtime.getRuntime().exec("python test.py"),它只包含很少的导入,但是它失败并出现错误1。我跟踪了错误,发现一些库没有找到:

Traceback (most recent call last):
File "/Users/firetiti/NetBeans/FiReTiTiLiB/Test.py", line 6, in <module>
from PIL import Image
ImportError: No module named PIL

当我在终端中执行相同的脚本时,一切都很好。于是我把python换成了pythonRuntime.getRuntime().exec("/somewhere/in/my/computer/python3.6 test.py")的绝对路径,果然奏效了。

所以看来Runtime.getRuntime().exec没有使用配置好的python版本。我该如何解决?

【问题讨论】:

    标签: java runtime.exec


    【解决方案1】:

    如果您在 Java 中运行 exec("python test.py"),将尝试以与任何其他应用程序相同的方式将 python 解析为可执行文件。

    假设你使用的是 UNIX、Linux 或 Mac OSX,顺序大致如下:

    1. JVM 执行fork 系统调用以创建子进程。子进程继承父(JVM)进程的环境变量。

    2. 子进程执行 exec 系统调用,将命令名称、参数和环境变量传递给它。

    3. 如果命令名称是简单名称,系统调用会尝试通过在命令搜索路径上的目录中搜索可执行文件来将该名称解析为路径名;即具有适当的执行权限集的人。

    4. 如果找到可执行文件,则根据其签名将其加载到子进程或解释为脚本。

    在您的情况下,第 3 步不起作用。具体来说,它会在搜索路径上找到错误版本的python。搜索路径由 PATH 环境变量确定...继承自父 JVM。

    因此,如果您在交互式 shell 和 Java 中得到不同的结果,那很可能意味着它们具有不同的 PATH 变量。这是首先要检查的。例如,在您的 Java 应用程序中,查看以下输出:

      System.out.println(System.environ().get("PATH"));
    

    并检查它找到的第一个python 命令是您想要的版本。

    可能的解决方案:

    • 在启动 JVM 之前适当设置 PATH
    • 使用ProcessBuilder在修改后的环境下执行外部命令
    • python 命令使用绝对路径名。
    • 如果这是 Python 2 vs 3,请将命令名称指定为 python2python3。 (典型的 Linux 软件包等会从 python2python3 链接到正确的可执行文件。)

    【讨论】:

    • 非常感谢您的详尽回答。我使用System.getenv("PATH") 来显示变量,确实缺少很多东西,但是当我在终端中运行命令echo $PATH 时它们就出现了。所以看来我最好的选择是我已经使用过的那个(你的第三个要点“绝对路径名”)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 2016-03-22
    相关资源
    最近更新 更多