【问题标题】:Runtime.getRuntime.exec() works on Windows but not LinuxRuntime.getRuntime.exec() 适用于 Windows 但不适用于 Linux
【发布时间】:2013-06-28 23:55:53
【问题描述】:

我正在构建一个 Java 应用程序,它调用系统命令并在将控制权返回给 Java 线程之前执行该命令。我的调试步骤是我制作了一个名为 test.pl 的 perl 脚本,我从 Java 方法调用该脚本,在 Windows 中,我得到预期的输出和返回值 0。在 Linux 中,我没有得到任何输出或错误输出,我得到 136 的返回值。我在网上花费了大量时间试图找出哪里出错了,但正如我所说,它在 Windows 上运行。我认为这一定是一个我没有发现的简单错误。

这里是来自http://www.javaworld.com/jw-12-2000/jw-1229-traps.html优秀的 Runtime.exec() 教程的代码

try {

    FileOutputStream fos = new FileOutputStream("output/" + this.startPosition + ".txt");
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(new String[]{"perl", "/data/stat-positive-selection/thaddeus/treesim/chr2YRI/test.pl"});

//System.out.println(commandLine);
// any error message?
StreamGobbler errorGobbler = new 
   StreamGobbler(proc.getErrorStream(), "ERROR");            

// any output?
StreamGobbler outputGobbler = new 
    StreamGobbler(proc.getInputStream(), "OUTPUT", fos);

// kick them off
errorGobbler.start();
outputGobbler.start();

// any error???
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);

fos.flush();
fos.close(); 
} catch (Throwable e){
    e.printStackTrace();
    }
}

我已经弄清楚并修复了代码

新的exec调用,需要使用shell和perl的路径

Process proc = rt.exec(new String[]{"/bin/bash", "-c", "/usr/bin/perl /data/stat-positive-selection/thaddeus/treesim/chr2YRI/test.pl"});

【问题讨论】:

  • 你确认你可以从命令行运行perl /data/stat-positive-selection/thaddeus/treesim/chr2YRI/test.pl,就像你的java代码运行的那个用户吗?
  • 不要使用Runtime.exec(),使用ProcessBuilder
  • 我想通了 new String[]{"/bin/bash", "-c", "/user/bin/perl /pathToTest/test.pl"}
  • 请注意这是/usr/bin/perl,而不是/user/bin/perl

标签: java linux runtime.exec


【解决方案1】:

新旧版本的区别在于:

  • 您正在从 shell 运行命令,并且
  • 您正在指定“perl”命令的完整路径名。

事实上,在这种情况下,从 shell 运行命令似乎没有什么意义。 (假设您的 Perl 应用程序可能依赖于在 shell 初始化期间设置的环境变量。但是,相同的环境变量通常会被 Java 命令的环境继承,然后从 Java 命令的环境继承。所以除非 Java 命令是以一种奇怪的方式启动,这种情况......不太可能。)

所以我认为 substantative 区别1 是您使用“perl”的完整路径名......而您没有子shell 来执行此操作。

所以,为了科学的利益(:-))我建议你试试这个:

    Process proc = rt.exec(new String[]{
            "/usr/bin/perl", 
            "/data/stat-positive-selection/thaddeus/treesim/chr2YRI/test.pl"});

1 - ... 与众不同的区别

【讨论】:

  • 我最终用 Apache Commons Exec 库替换了整个代码。
【解决方案2】:

我用 Apache Commons Exec 库替换了整个 Runtime.exec() 结构。它解决了我遇到的问题。

http://commons.apache.org/proper/commons-exec/tutorial.html

【讨论】:

  • 但这并不能解释为什么替换代码可以解决问题,因此并不能真正帮助其他人。
  • 我发现了同样的问题。在我的调试环境中运行良好,当我将它移到我的盒子时,它似乎切断了参数或其他东西......如果有解决方案会很好......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 2016-03-01
  • 2021-05-02
  • 2017-06-14
  • 2011-06-15
  • 2021-10-27
相关资源
最近更新 更多