且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在java中执行linux命令并将输出存储在变量中

更新时间:2023-11-11 21:42:46

首先,不要使用Runtime.exec。始终使用 ProcessBuilder ,它更可靠可预测的行为。

First, don't use Runtime.exec. Always use ProcessBuilder, which has much more reliable and predictable behavior.

其次,字符串中的所有内容都作为单个命令传递,包括垂直条。你没有将它传递给shell(比如/ bin / bash),所以相互之间的管道命令不起作用。

Second, everything in your string is being passed as a single command, including the vertical bars. You are not passing it to a shell (like /bin/bash), so piping commands to one another won't work.

第三,你需要使用命令输出正在运行。如果你调用 waitFor()然后尝试读取输出,它有时会工作,但它也会在很多时候失败。这种行为是高度依赖操作系统的,甚至可以在不同的Linux和Unix内核和shell之间变化。

Third, you need to consume the command's output as it is running. If you call waitFor() and then try to read the output, it may work sometimes, but it will also fail much of the time. This behavior is highly operating system dependent, and can even vary among different Linux and Unix kernels and shells.

最后,你不需要 grep wc 。你有Java。在Java中做同样的事情非常简单(并且可能比尝试调用shell更容易,因此管道可以工作):

Finally, you don't need grep or wc. You have Java. Doing the same thing in Java is pretty easy (and probably easier than trying to invoke a shell so piping will work):

ProcessBuilder builder =
    new ProcessBuilder("asterisk", "-rx", "ss7 linestat");
builder.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE);
Process p = builder.start();

int freeE1s = 0;
try (BufferedReader buf =
        new BufferedReader(new InputStreamReader(p.getInputStream()))) {
    String line;
    while ((line = buf.readLine()) != null) {
        if (line.contains("Idle")) {    // No need for 'grep'
            freeE1s++;                  // No need for 'wc'
        }
    }
}

p.waitFor();

System.out.println(freeE1s);

从Java 8开始,你可以缩短它:

As of Java 8, you can make it even shorter:

ProcessBuilder builder =
    new ProcessBuilder("asterisk", "-rx", "ss7 linestat");
builder.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE);
Process p = builder.start();

long freeE1s;
try (BufferedReader buf =
        new BufferedReader(new InputStreamReader(p.getInputStream()))) {
    freeE1s = buf.lines().filter(line -> line.contains("Idle")).count();
}

p.waitFor();

System.out.println(freeE1s);