processbuilder的inputstream为空,具体取决于操作系统

anauzrmj  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(350)

我编写了这段简单的代码来测试processbuilder:

@SpringBootApplication
public class TerminalDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(TerminalDemoApplication.class, args);
        try {
            System.out.println("hello");
            Process process = new ProcessBuilder("python", "--version").start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

}

它在windows中工作(返回我系统的python版本),但在我的macbook中相同的代码返回行尾,所以基本上是空的。?这需要根据操作系统进行进一步配置?为什么会这样?

bsxbgnwa

bsxbgnwa1#

您得到了什么错误代码?
有(至少)两种解释;该错误代码将指示它是哪一个。

您没有运行python,也没有运行“错误”的python

这意味着您将获得某种类型的错误代码或异常。
原因可能是路径问题。
跑步 python ,就像那样-就像在中一样,根本没有路径信息,名义上是必须被破坏的:这不是你的操作系统的工作方式,它不知道如何处理这个路径。
将这样一个命令解释为“哦,实际上,遍历 $PATH 环境变量,并将该路径粘贴在该名称前面,查看是否在其中找到可执行文件。如果你这样做了,运行它并停止)。
java基本上不参与任何Bashism。但是,在一些奇怪的地方,它确实做到了——当您使用单字符串版本的 new ProcessBuilder ),这是一个shellism,它确实尝试进行基本的路径查找,但这只是它的结束。不行 * 解包,在windows上是操作系统级的事情,但在posix系统上是一种空壳主义。
我强烈建议您避免java的基本外壳主义。它是不可靠的,并且高度特定于操作系统。
所以:始终显式地传递参数(很好,您正在这样做),始终使用 ProcessBuilder (很好,你正在这么做),永远不要使用相对路径(这就是你出错的地方)。

它将进入错误流

操作系统上的进程通常连接到3个管道,而不是2个。有“标准输入”、“标准输出”和“标准错误”。您自己的java进程将这些公开为 System.out , in ,及 err .
特别是在linux中,将标准从某个进程重定向到某个文件或另一个进程是很常见的。
这意味着标准err自然具有它倾向于向控制台发出的属性,即使您正在重定向内容。换句话说,“标准输出”和“标准错误”这两个术语在posix上是非常愚蠢的名称。更好的命名应该是“标准流程输出”和“标准流程消息”。
要求python打印其版本有点不确定。字符串“Python V3.0.1”或WHATNOT当然不是一个错误,但是如果人们认为这是“进程的输出”,那就有点可疑了。Python工具的作者很可能会把更多的信息“我应该打印给你”,即使你正在重定向的东西。
因此,我的猜测是,这个版本正在走向标准错误。
您可以通过两种方式解决此问题:也可以从标准err读取,或者使用process builder的功能:您可以要求它将标准输出和标准err捆绑到单个流中( .redirectErrorStream(true) ).
如果这个解释是正确的,我希望退出代码是0。

相关问题