如何通过Java的Runtime.getRuntime()。exec方法调用此命令?

时间:2015-05-19 00:38:05

标签: java linux process runtime.exec

以下命令在我的Linux终端中正确运行:

java -Djava.library.path=/home/john/native_so_libraries/linux-64 -cp '/home/john/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/j‌​ohn/Desktop/Dropbox/Libjitsi_linux_64/*' Main "send"

此命令为本机.so库(通过Djava.library.path = / ...)指定一个文件夹,一个名为“SendReceive.jar”的应用程序JAR文件,一个用于JAR库的文件夹(通过-cp classpath选项) ),还有一个包含要运行的main方法的主类,一个名为“Main”的类。它有一个命令行参数,用引号括起来,即“send”参数。这个命令从终端运行并运行一个Java进程,但我无法弄清楚如何让它与另一个进程的Runtime.getRuntime()。exec一起使用。

请注意,我正在尽力遵循本教程中提供的说明:http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html?page=2 - 这意味着我使用线程来使用进程中的标准输入和标准错误流。但是,当我将终端命令变成这样的字符串时,进程将不会启动:

Process process = Runtime.getRuntime().exec("java -Djava.library.path=/home/john/native_so_libraries/linux-64 -cp '/home/john/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/j‌​ohn/Desktop/Dropbox/Libjitsi_linux_64/*' Main \"send\"");

如何通过Runtime.getRuntime()。exec?

运行此命令

2 个答案:

答案 0 :(得分:3)

简短的回答是不要。请改用ProcessBuilder。它允许您将每个命令行参数分隔为它自己的String,这将显示为进程的单独“参数”。这使得处理包含空格的路径非常有用,例如......

ProcessBuilder pb = new ProcessBuilder(
                "java", 
                "-Djava.library.path=/home/johnmichaelreed/Desktop/Dropbox/Libjitsi_linux_64/lib/native/linux-64", 
                "-cp", 
                "/home/johnmichaelreed/NetBeansProjects/SendReceive/dist/SendReceive.jar:/home/j‌​ohnmichaelreed/Desktop/Dropbox/Libjitsi_linux_64", 
                "Main", 
                "\"send\"");

pb.redirectErrorStream(true);
try {
    Process p = pb.start();
    try (InputStream is = p.getInputStream()) {
        int in = -1;
        while ((in = is.read()) != -1) {
            System.out.print((char)in);
        }
    }
    int exitCode = p.exitValue();

    System.out.println("Process exited with " + exitCode);
} catch (IOException ex) {
    ex.printStackTrace();
}

它还允许您将stderr重定向到stdout,以便于阅读。

您还应该阅读stdout并检查退出值以获得更好的digansotics

答案 1 :(得分:1)

您需要做的第一件事是执行glob(在类路径中由*表示)。您还可以使用ProcessBuilder - 其中用于创建操作系统进程。并且,List<String>或命令以及要执行的StringBuilder水珠。像,

public static void main(String[] args) {
    String home = System.getProperty("user.home");
    System.out.println(home);
    List<String> command = new ArrayList<>();
    command.add("java");
    command.add("-Djava.library.path=" + home
            + "/native_so_libraries/linux-64");
    StringBuilder cp = new StringBuilder();
    cp.append(home + "/NetBeansProjects/SendReceive/dist/SendReceive.jar");
    try {
        File dir = new File(home + "/Desktop/Dropbox/"
                + "Libjitsi_linux_64/");
        for (File f : dir.listFiles()) {
            if (f.isFile()) {
                cp.append(":").append(f.getCanonicalPath());
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    command.add("-cp");
    command.add(cp); // <-- shouldn't need literal
                    // single quotes.
    command.add("Main");
    command.add("send"); // <-- shouldn't need literal double quotes.
    ProcessBuilder pb = new ProcessBuilder(command);
    pb.inheritIO();
    try {
        Process p = pb.start();
        System.exit(p.waitFor());
    } catch (Exception e) {
        e.printStackTrace();
    }
}