Java Runtime.getRuntime()。exec运行可执行文件'带参数

时间:2015-02-08 12:36:48

标签: java runtime exec

我正在尝试在Java中运行由c生成的可执行文件。最初,我可以使用

在终端上运行它
./bin/svm-train -s 0 -t 0 -d 3 -g 0.0 -r 0.0 -n 0.5 -m 40.0 -c 1.0 -e 0.001 -p 0.1 ./data/trainfile ./model/update.model

终端上的此命令运行良好,生成文件'update.model'需要几秒钟,如代码中所示。

但是当我尝试使用以下代码将此过程放入Java时,程序结束而不生成'update.model'

String[] cmdUpdateTrain = new String[]{"/bin/bash", "-c", "./bin/svm-train -s 0 -t 0 -d 3 -g 0.0 -r 0.0 -n 0.5 -m 40.0 -c 1.0 -e 0.001 -p 0.1 ./data/trainfile ./model/update.model"};
Runtime.getRuntime().exec(cmdUpdateTrain);

如果我尝试使用Java下面的代码,它也可以正常生成模型。

String[] cmdUpdateTrain = new String[]{"/bin/bash", "-c", "./bin/svm-train ./data/trainfile ./model/update.model"};
Runtime.getRuntime().exec(cmdUpdateTrain);

所以我认为这可能是./bin/svm-train处理参数的问题。


我发现了为什么会这样。这是因为程序在执行./bin/svm-train之前结束。 以下代码解决了这个问题。

try{
    String[] cmdUpdateTrain = new String[]{"/bin/bash", "-c", "./bin/svm-train -s 0 -t 0 -d 3 -g 0.0 -r 0.0 -n 0.5 -m 40.0 -c 1.0 -e 0.001 -p 0.1 ./data/trainfile ./model/update.model"};
    Process psTrain = Runtime.getRuntime().exec(cmdUpdateTrain);
    psTrain.waitFor();
}catch(InterruptedException interupt){
}

1 个答案:

答案 0 :(得分:0)

  

调用Runtime.getRuntime()。EXEC(cmdUpdateTrain)

唐'吨。使用。的Runtime.exec()。

您的命令行有几个问题。

首先:您是否注意到命令的开头以及两个文件参数的路径?它们与您启动命令的目录相关;这不太可能与启动Java程序的目录相同,因此只能失败。

第二:你使用命令解释器。为什么呢?

第三:stdin,stdout,stderr怎么样?你的程序输出什么吗?如果是,你怎么处理这个?

与在Java中运行外部进程一样,解决方案是使用ProcessBuilder

final Path basedir = Paths.get("whereyourprogramislaunched");
final Path stdout = Paths.get("somewheretooutputstdout");
final Path stderr = Paths.get("somewheretooutputstderr");

final ProcessBuilder builder = new ProcessBuilder(
    "./bin/svm-train", "-s", "0", "-t", "0", "etc", "etc"
);

pb.directory(basedir.toFile());
pb.redirectOutput(stdout.toFile());
pb.redirectError(stderr.toFile());

final Process process = builder.start();

// Deal with process exit code