首页 > 解决方案 > 如何从 Java 运行 Linux 脚本(已添加到 $PATH)?

问题描述

我正在尝试使用 运行脚本Runtime.getRuntime().exec,但没有任何反应。这是我的意思的一个例子:

class Test {
    public static void main(String[] args) throws Exception {
        Runtime.getRuntime().exec("script.sh");
        System.out.println("done");
    }
}

这是script.sh

#!/bin/sh
echo "It works"

我已将 sh 文件的位置添加到 PATH 中,因为我不想硬编码它的位置。在终端中,上述脚本都可以在任何位置(目录)工作:

$ script.sh
It works

但不是通过Java:

$ javac Test.java && java Test
done

这是我所期望的:

$ javac Test.java && java Test
It works
done

为什么我没有得到脚本的输出,或者至少没有错误消息?

标签: javashell

解决方案


您有责任确保命令写入 stdout 或 stderr 的任何数据都出现在您的应用程序中。

如果你没有明确地做任何事情,消息将不会显示在任何地方。相反,它们会被卡在某处的管道缓冲区中。这是您没有script.sh依赖项ls的示例,用作编写输出和错误的示例:

$ ls -d /tmp /doesntexist
ls: /doesntexist: No such file or directory
/tmp

$ cat Test.java
class Test {
    public static void main(String[] args) throws Exception {
        Runtime.getRuntime().exec("ls -d /tmp /doesntexist");
    }
}

$ javac Test.java && java Test
(no output)

如果您只想在运行 Java 程序的终端上显示输出和错误,让进程继承 Java 的 stdout/stderr:

$ cat Test.java
class Test {
    public static void main(String[] args) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("ls", "-d", "/tmp", "/doesntexist");
        pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
        pb.redirectError (ProcessBuilder.Redirect.INHERIT);
        pb.start();
    }
}

$ javac Test.java && java Test
ls: /doesntexist: No such file or directory
/tmp

推荐阅读