我试图让我的Java程序与Linux bash交互,但出了点问题.我有一个简单的可执行程序prog,从stdin读取一个整数并输出其正方形.执行
echo 5 | ./prog
从bash本身打印正确的答案25在标准输出但运行
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.解决办法是什么?
解决方法:
Java exec无法像这样运行shell命令.如果要运行shell命令,则需要显式调用shell;例如
Process proc = run.exec(new String[]{"/bin/sh", "-c", "echo 5 | ./prog"});
有关Java如何处理此问题的更多详细信息,请阅读exec(String)
和exec(String[])
的javadoc.请注意,这些是“便捷方法”,您需要遵循指向底层方法的链接链,以便全面了解javadoc所说的内容. .
如果您想了解Java如何处理这个问题的更多细节,那么有源代码……
如果您想深入理解为什么Java本身不处理shell语法,您可能需要深入研究UNIX / Linux系统的体系结构和原理,以及应用程序,操作系统和命令shell之间的关注点分离.请注意,有无数不同的shell,每个shell都有(可能)不同的引用,参数拆分,重定向,管道等规则.大多数流行的外壳都很相似,但这就是事情的发展方式.
解决方案的解释:
>手动拆分命令的原因是exec(String)不会将命令正确地拆分为单个命令和参数.它不能.这是一个管道中有两个命令的示例.
>使用“sh”的原因是……嗯……你需要一个shell来解析和处理shell命令行. Java的exec命令不支持shell语法…正如javadoc所解释的那样.
>“-c”选项的目的由“man sh”解释.基本上,sh -c“a b c”表示“使用’sh’来运行命令行’a b c’”.
FWIW,技术上可以仅用Java构建和运行管道(即不依赖于外壳),但通常不值得努力.您已经通过运行外部命令引入了平台依赖性,因此以特定shell命令和语法形式的额外依赖性不会使事情变得更糟.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。