【发布时间】:2014-06-23 15:59:30
【问题描述】:
我想用 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 获取标准错误时,它确实会每秒读取一个值,但它总是会读取 null。
【问题讨论】:
-
我怀疑 sudo 是问题
-
我在 perf 手册页中找不到任何
-I选项的提及...您使用的是什么发行版和版本的 perf?您确定可以从 shell 成功运行该命令吗? -
读取标准错误,而不仅仅是标准输出。它会告诉你出了什么问题。
-
我添加了更多信息来解决 cmets。
-
由于 readLine() 阻塞,你不需要 sleep()。