1

我正在构建一个 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();
    }
}

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

new exec call, the use of the shell and the path to perl are required

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

2 回答 2

1

The differences between the old and new versions are:

  • you are running the command from a shell, and
  • you are specifying the full pathname of the "perl" command.

In fact, in this context there doesn't seem to be a great deal of point in running the command from a shell. (Hypothetically, your Perl application might depend on environment variables that are set during shell initialization. However, the same environment variables would normally be inherited by and then from the Java command's environment. So unless the Java command is being launched in a strange way, this scenario is ... unlikely.)

So I think the substantative difference1 is that you are using the full pathname for "perl" ... and you don't a subshell to do that.

So, in the interests of science ( :-) ) I suggest you try this:

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

1 - ... the difference that makes a difference

于 2013-06-29T01:26:05.930 回答
1

I replaced the whole Runtime.exec() structure with the Apache Commons Exec library. It fixed the problem I was having.

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

于 2013-07-02T12:37:56.707 回答