为什么我的Java代码不正确地执行bash命令?

我正在尝试使我的Java程序与Linux bash交互,但出现了一些问题。 我有一个简单的可执行文件,从stdin读取一个整数,并输出其正方形。 执行

 echo 5 | ./prog 

从bash本身打印正确的答案25stdout但运行

 import java.io.*; public class Main { public static void main(String[] args) throws InterruptedException, IOException { Runtime run = Runtime.getRuntime(); Process proc = run.exec("echo 5 | ./prog"); proc.waitFor(); BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); while(br.ready()) System.out.println(br.readLine()); } } 

竟然给了5 | ./prog 5 | ./prog 。 解决办法是什么?

Java exec不能像这样运行shell命令。 如果你想运行一个shell命令,你需要明确地调用shell; 例如

 Process proc = run.exec(new String[]{"/bin/sh", "-c", "echo 5 | ./prog"}); 

有关更多详细信息,请阅读exec(String)exec(String[])的javadocs。 请注意,这些是“便利的方法”,您需要遵循链接到底层方法的链接,以全面了解javadoc的说法。

如果你想要更多的细节,有源代码…

说明:

  • 手动分割命令的原因是exec(String)不会将命令正确地分割成单个命令和参数 。 它不能。 这是一个管道中有两个命令的例子。

  • 使用“sh”的原因是…呃…你需要一个shell来解析和处理一个shell命令行。 Java的exec命令不支持shell语法……正如javadoc解释的那样。

  • “-c”选项的用途由“man sh”解释。 基本上, sh -c "abc"意思是“使用'sh'来运行命令行'ab c'”。

FWIW,在技术上可以仅用Java构建和运行管道(即不依靠外部壳体),但通常不值得付出努力。 您已经通过运行外部命令引入了平台依赖关系,因此以特定的shell命令和语法形式的额外依赖关系不会使事情变得更糟。