#java #command-line #terminal
#java #командная строка #терминал
Вопрос:
Я немного смущен тем, почему я не могу выполнить следующую команду ls -l
, если я запускаю ls
или pwd
она работает нормально.
Я что-то упустил?
ProcessBuilder pb = new ProcessBuilder("ls -l");
pb.redirectErrorStream(true);
Process process = pb.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ( (line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
Еще один вопрос: как я могу запускать несколько системных команд одновременно? Используя цикл while или циклы for, команды будут выполняться одна за другой. Любой совет?
Заранее спасибо.
Комментарии:
1. Попробуйте
new ProcessBuilder("ls", "-l");
2. Зачем вам это нужно ?! Используйте функциональность, встроенную в JDK, и сохраняйте независимость вашего кода от платформы.
3. чтобы посмотреть, можно ли это сделать или возможно ли это. любопытный ум хочет знать 🙂
Ответ №1:
Изменить:
new ProcessBuilder("ls -l");
Для:
new ProcessBuilder("ls", "-l");
Комментарии:
1. Спасибо. Еще один вопрос. Допустим, у меня есть массив системных команд. Как мне это сделать?
2. Я понял … если кому-то интересно, вот оно
3. String[] st = {«ls», «bin»}; ProcessBuilder pb = новый ProcessBuilder(st);
Ответ №2:
String[] st = {"ls", "bin"};
ProcessBuilder pb = new ProcessBuilder(st);
pb.redirectErrorStream(true);
Process process = pb.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ( (line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
Ответ №3:
Используя цикл while или циклы for, команды будут выполняться одна за другой.
Только тогда, когда вы выполняете весь процесс запуска, а затем чтения стандартного вывода для каждого из них, один за другим. Процессы действительно выполняются параллельно, это просто часть чтения, которая мешает вам запускать их одновременно. Все, что вам нужно сделать, это разбить start и read на две части:
Stream.of(Arrays.asList("ls", "-l"),
Arrays.asList("python", "-h"),
Arrays.asList("df"))
.map(cmd->{
// Create a process for each command, but don't read the output
try {
return new AbstractMap.SimpleImmutableEntry<>(cmd,
new ProcessBuilder(cmd)
.redirectErrorStream(true)
.start().getInputStream());
} catch (IOException e) {
e.printStackTrace();
return null;
}
})
.filter(p->p!=null)
.parallel()
.forEach(in->{
// Read and print STDOUT for each process.
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in.getValue()))){
String line;
while ((line = reader.readLine()) != null) {
System.out.printf(" s: %sn", in.getKey(), line);
}
} catch (IOException e) {
e.printStackTrace();
}
});
parallel()
Вызов делает вывод действительно трудным для чтения, он используется только для демонстрации того, что процессы действительно выполняются одновременно.
Комментарии:
1. Спасибо за совет. Нужно больше практиковаться.
2.
cmd.split("\s ")
не учитывает кавычки или экранированные кавычки и, как правило, является очень плохой идеей.3. Спасибо, я изменю ответ.