Java getRuntime 执行

Java getRuntime Exec

我在 Java 1.8 上调用 p = Runtime.getRuntime().exec(command)。 该命令调用 bash 脚本如下:

#!/bin/bash
args=("$@")
cat /home/user/Downloads/bigtext.txt | grep ${args[0]}

上面的 bash 脚本在使用命令行调用时工作正常。当使用 exec() 在我的 Java 应用程序中调用时,我没有返回任何 CAT 输出。它似乎没有通过 p.waitFor();我哪里错了?

如果我直接运行一个命令,例如"ls -alF",一切都会按预期工作。

$ java -version java version "1.8.0_31" Java(TM) SE Runtime Environment (build 1.8.0_31-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)


String tmp = "/home/user/search "+input;        
System.out.println(tmp); //  /home/user/search sometextarg
String woa = executeCommand(tmp);


private String executeCommand(String command) {     
        StringBuilder output = new StringBuilder();
                BufferedReader reader = null;
        Process p;
        try {
            p = Runtime.getRuntime().exec(command);
            p.waitFor();

                        reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

            String line = "";

            while ((line = reader.readLine())!= null) {
                output.append(line + "\n");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return output.toString();
    }

你的Java进程和你的脚本死锁了互相等待:你正在等待进程退出,进程正在等待你读取输出。

它恰好适用于 ls -alF 和其他具有小输出的命令,因为它们都适合管道的缓冲区(在我的系统上为 64kib)。

只需将 p.waitFor() 移到 while 循环下方,您的运气就会更好:

private String executeCommand(String command) {     
    StringBuilder output = new StringBuilder();
            BufferedReader reader = null;
    Process p;
    try {
        p = Runtime.getRuntime().exec(command);
        reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

        String line = "";
        while ((line = reader.readLine())!= null) {
            output.append(line + "\n");
        }
        p.waitFor();

    } catch (Exception e) {
        e.printStackTrace();
    }
    return output.toString();
}

如果您还希望它能正确处理包含空格和某些其他字符的值,您必须:

  1. 在您的脚本中引用 "${args[0]}"
  2. 重写您的 executeCommand 以使用 Runtime.exec(String[]) 而不是 Runtime.exec(String)