Я хочу получить в 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" она работает правильно, и я получаю значения по строкам.
EDIT: сама команда работает нормально, когда я запускаю ее непосредственно из командной строки. Опция -I была представлена в более новых версиях ядра, раньше она не существовала (я использую ядро 3.11, Ubuntu).
При использовании 2> $ 1, чтобы получить также stderr, он действительно будет читать значение каждую секунду, но он всегда будет читать значение null.
Проблема заключается в том, что перт stat не использует stdout по умолчанию, а stderr. См. Параметр log-fd.
Таким образом, вы можете либо перенаправить stderr в stdout в команду, которую используете,
Или вы захватываете входной поток из stderr процесса
-I
варианта в PErF страниц человека ... то , что дистрибутив и версия перфорации вы используете? Вы уверены, что можете успешно выполнить эту команду из оболочки?