从Java Runtime exec()使用/bin/bash重新录制

从Java Runtime exec()使用/bin/bash重新录制,java,linux,bash,runtime.exec,Java,Linux,Bash,Runtime.exec,我试图在Ubuntu 14.04上使用java.lang.Runtime的exec()-方法执行的命令中使用重定向 public static void main(String[] args) throws IOException, Exception { Runtime runtime = Runtime.getRuntime(); String command = "echo bla > bla.txt"; System.out.println("Command

我试图在Ubuntu 14.04上使用
java.lang.Runtime
exec()
-方法执行的命令中使用重定向

public static void main(String[] args) throws IOException, Exception {
    Runtime runtime = Runtime.getRuntime();
    String command = "echo bla > bla.txt";
    System.out.println("Command : " + command);
    Process process = runtime.exec(command);
    printLines(" stdout", process.getInputStream());
    printLines("  error", process.getErrorStream());
    process.waitFor();
    System.out.println("ExitValue : " + process.exitValue());
}

private static void printLines(String name, InputStream ins) throws Exception {
    try(Stream<String> lines = new BufferedReader(new InputStreamReader(ins)).lines()) {
        lines.forEach(line -> System.out.println(name + " : " + line));
    }
}
所以
bla>bla.txt
被写入
stdout
,但是当然没有重定向到
bla.txt

可能在简单的
exec()
中不可能执行shell重定向

因此我尝试更改
命令=“/bin/bash-c'echo bla>bla.txt”
以使用整个echo并将其重定向为
/bin/bash
的参数

有了这个,我得到了结果:

Command : /bin/bash -c 'echo bla > bla.txt'
  error : bla: -c: line 0: unexpected EOF while looking for matching `''
  error : bla: -c: line 1: syntax error: unexpected end of file
ExitValue : 1
当然,
/bin/bash-c'echo bla>bla.txt'
在Ubuntu上运行良好,可以创建所需的文件

我找不到可以设置单引号以获得满意结果的地方,我还尝试使用各种转义字符来转义空格或重定向(

如果我使用命令数组,比如

String cmdArray[] = {"/bin/bash", "-c", "echo bla > bla.txt"};
Process process = runtime.exec(cmdArray);
,但它必须是单个字符串,因为整个命令必须在其他地方生成

我当然知道

  • 有更好的方法将字符串写入文件
  • 在其他地方执行命令可能不是个好主意
  • 等等

我只是好奇为什么这不起作用。

原因是exec使用带有任何空格的简单StringTokenizer作为分隔符来解析实际命令。因此,它是可移植的,因为当您传递复杂的内容时,它不会在任何地方工作:-)

您选择的解决方法是正确的、可移植的,而且最安全的是,如果命令包含引号等,您不需要转义

String command = "echo bla > bla.txt";
Process process = runtime.exec(command);
命令中的
>blah.txt
文本是重定向标准输出的shell语法。它由类似
sh
bash
的shell实现

Runtime.exec()
不使用shell来运行命令。下面介绍了它启动命令的方式。基本上,它使用自己的逻辑将命令字符串拆分为空格处的参数,然后直接执行生成的命令

如果要调用应解释为shell命令的命令,则需要显式调用shell:

String[] command = { "/bin/bash", "-c", "echo bla > bla.txt" };
Process process = runtime.exec(command);

这就是为什么我尝试使用原始命令调用
/bin/bash
,并将其重定向为参数。你的回答已经是我问题的一部分。在我看来,你问题的重点是为什么其他解决方案不起作用。这就是我回答的问题。正如您所同意的,以列表形式提供参数确实有效;你只是有一个架构上的原因,为什么你不能这样做。我懒得去关注链接。我想知道为什么
exec(“/bin/bash-c'echo bla>bla.txt”)不起作用,第一个链接后面关于
StringTokenizer
的部分给出了解释。感谢您的反馈。我们如何使用String[]方法获得输出?我当时正在使用
while((s=stdInput.readLine())!=null)
,但现在不再使用了works@MikePalmice如果你遇到了问题,你应该问一个新问题,包括那些不适合你的代码。看,似乎是对的<代码>“/bin/bash”“-c”“echo”“bla”“>”“bla.txt”“
-单个令牌-在命令行上给出相同的结果。真遗憾。
String[] command = { "/bin/bash", "-c", "echo bla > bla.txt" };
Process process = runtime.exec(command);