我正在尝试在Ubuntu 14.04上使用exec()
- java.lang.Runtime
方法执行的命令中使用重定向
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));
}
}
输出结果为:
Command : echo bla > bla.txt
stdout : bla > bla.txt
ExitValue : 0
因此bla > bla.txt
写入stdout
,但当然没有重定向到bla.txt
。
在简单的exec()
中无法进行Perhapes shell重定向。
所以我尝试更改command = "/bin/bash -c 'echo bla > bla.txt'"
以使用整个回显并将其重定向为/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);
,但它必须是单个字符串,因为整个命令必须在其他地方构建。
我当然知道
我只是好奇为什么这不起作用。
答案 0 :(得分:1)
原因是exec使用带有任何空格的简单StringTokenizer作为解析实际命令的分隔符。因此它是便携式的,因为当你传递复杂的东西时它无处可用: - )
您选择的解决方法是正确的方式,可移植且最重要的是最安全的,因为如果命令包含例如引号等,则您需要逃脱。
答案 1 :(得分:1)