我想用 Java 接收 Linux 命令行程序的输出。我需要逐行读取值,因为实用程序每秒报告一次它们的值,Java 程序不需要等到执行结束。它应该每秒接收一次值。
下面的小程序在 ping
命令的情况下工作正常,但在 perf stat
命令的情况下却不行。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
Process p;
BufferedReader reader;
public Main(int number) throws IOException {
if (number == 1) {
// does NOT work, blocks on readLine()
p = Runtime.getRuntime().exec("sudo perf stat -e cycles -I 1000 -p 9264"); // change PID to the one to be monitored
}
else if (number == 2) {
// WORKS!
p = Runtime.getRuntime().exec("ping www.google.com");
}
else {
System.out.println("Either 1 or 2...");
System.exit(0);
}
reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
}
public void process() throws IOException {
String res = "";
res = reader.readLine();
System.out.println(res);
}
public static void main (String[] args) throws IOException, InterruptedException {
Main myMain = new Main(Integer.parseInt(args[0]));
while (true) {
myMain.process();
Thread.sleep(1000);
}
}
}
所以当运行 java Main 2
时它工作正常,但是当调用 java Main 1
时它会阻塞在 reader.readLine()
打电话。
这两个命令有什么区别?同样使用命令“ls -l”它可以正常工作并且我逐行接收值。
编辑: 当我直接从命令行运行它时,该命令本身工作正常。 -I 选项是在较新的内核版本中引入的,它以前不存在(我使用的是内核 3.11,Ubuntu)。
当使用 2>$1 也获取 stderr 时,它确实会每秒读取一个值,但它始终读取 null。
最佳答案
问题似乎是 perf stat 默认不使用 stdout,而是 stderr。 See the log-fd option .
所以你可以redirect stderr to stdout在您使用的命令中,
或者您从 stderr of the Process 捕获输入流
关于java - 每秒从 Java 程序中的 Linux 实用程序接收值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24370328/