Runtime.getRuntime.exec()适用于Windows但不适用于Linux

时间:2013-06-28 23:55:53

标签: java linux runtime.exec

我正在构建一个调用系统命令的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"});

2 个答案:

答案 0 :(得分:1)

旧版和新版之间的差异是:

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

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

所以我认为替代差异 1 是你使用“perl”的完整路径名...而你没有子shell来做到这一点。

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

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

1 - ......产生差异的差异

答案 1 :(得分:0)

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

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