【问题标题】:Command works in terminal, but not with Runtime.exec命令在终端中有效,但不适用于 Runtime.exec
【发布时间】:2016-02-09 21:35:43
【问题描述】:

我正在尝试使用Runtime.getRuntime().exec(command) 从 Java 应用程序运行一些命令。但是,某些从命令行工具(如终端)运行的命令在这样执行时会失败。

例子:

private static final String COMMAND = "cp -n /home/me/Downloads/a.png /home/me/Downloads/b.png";
private static final String COMMAND_2 = "cp -n /home/me/Downloads/a.png /home/me/Downloads/b.png && cp -n /home/me/Downloads/a.png /home/me/Downloads/b.png";

public static void main(String[] args) throws Exception {
    int result = Runtime.getRuntime().exec(COMMAND).waitFor();
    System.out.println(result); // prints 0
    int result2 = Runtime.getRuntime().exec(COMMAND_2).waitFor();
    System.out.println(result2); // prints 1
}

请注意,COMMAND_2COMMAND 有两次相同的作用,由 && 分隔。为什么一个成功,另一个失败?两者都可以在终端中正常工作。

我在 Red Hat Enterprise Linux 6 上使用 Oracle-Java 1.7.0。

【问题讨论】:

  • 您可能需要为完全限定路径提供cp,例如/bin/cp.
  • 尝试将 && 替换为 ';' 来执行
  • 1.使用ProcessBuilder; 2.Process不是shell解释器!
  • @MiteshParmar 没有区别。 @fge 它到底是什么,即用于解释该命令的内容是什么?我发现它在以我的命令作为参数显式运行 bash 时有效。
  • 好吧,bash 是一个 shell 解释器的例子;而bash 本身就是一个进程。但是没有理由对进程使用bash,除非你执行一个shell脚本。

标签: java linux shell command-line


【解决方案1】:

这是Process 最常见的错误。

进程不是 shell 解释器。因此,任何特殊的 shell “关键字”都不会被解释。

如果你尝试执行cmd1 && cmd2,会发生什么是进程的参数实际上是cmd1&&cmd2。不要那样做。

更重要的是,不要使用Runtime.exec()。请改用ProcessBuilder。示例代码:

final Process p = new ProcessBuilder("cmd1", "arg1", "arg2").start();
final int retval = p.waitFor();

查看ProcessBuilder 的javadoc,它有很多细节。

哦,如果您使用 Java 7,甚至不用费心使用外部命令。 Java 7 有Files.copy()

还有,man execve

【讨论】:

  • 啊,谢谢。其他人开始使用命令,我认为最初的原因是tar 操作,可以通过这种方式快速而肮脏地完成。但是,是的,我也觉得它很老套。
【解决方案2】:

命令及其每个参数必须是字符串数组中的单独项。例如:

private static final String[] COMMAND = { "cp", "-n", "/home/me/Downloads/a.png", "/home/me/Downloads/b.png" };

....

int result = Runtime.getRuntime().exec(COMMAND).waitFor();

【讨论】:

  • 这不是问题所在。
猜你喜欢
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
相关资源
最近更新 更多