Я называю программы командной строки соединенными каналами. Все это работает над Linux наверняка.
Мой метод:
protected String execCommand(String command) throws IOException {
String line = null;
if (command.length() > 0) {
Process child = Runtime.getRuntime().exec(command);
InputStream lsOut = child.getInputStream();
InputStreamReader r = new InputStreamReader(lsOut);
BufferedReader in = new BufferedReader(r);
String readline = null;
while ((readline = in.readLine()) != null) {
line = line + readline;
}
}
return line;
}
Если я называю некоторый файл кошки | grep asd, я получаю ожидаемый результат. Но не все команды работает правильно. Например, с этим:
cat /proc/cpuinfo | wc -l
или это:
cat /proc/cpuinfo | grep "model name" | head -n 1 | awk -F":" '{print substr($2, 2, length($2))}
метод возвратит пустой указатель. Я предполагаю, что эта проблема зависит от выходных команд форматирования как голова, хвост, туалет, и т.д. Как я могу работать вокруг этой проблемы и получить конечный результат вывода?
До сих пор не нашла правильное решение для выполнения командных команд с помощью Runtime.exec, но нашел обходной путь. Я просто написал эти сценарии для разделения файлов Bash. Затем Runtime.exec вызывает эти сценарии Bash и получают ожидаемый результат.
Каждый, кто использует Runtime.exec, должен прочитать это .
Это может быть хорошая идея проверить поток ошибок процесса .
Труба (например, перенаправление или >
) является функцией оболочки, и поэтому выполнение непосредственно от Java не будет работать. Вам нужно сделать что-то вроде:
/bin/sh -c "your | piped | commands | here"
, который выполняет процесс оболочки с помощью командной строки (включая трубы), указанные после -C
(в цитатах).
Обратите внимание, что необходимо употреблять STDOUT
и STDERR
одновременно , в противном случае ваш выреченный процесс будет блокировать ожидание вашего процесса, чтобы потреблять вывод (или ошибки). Больше информации здесь .
Быстрая и грязная вещь, которую нужно сделать:
command = "/bin/sh -c '" + command.replaceAll("'", "'\''") + "'"
Обычно вам нужно следить за инъекцией оболочки (т.е. кто-то крадется "; rm -rf /;"
в команду). Но это проблема только в том случае, если часть команды может быть предоставлена другим пользователем.
Медленным и болезненным подходом было бы самому сделать конвейер Bash на Java. Если вы пойдете по этому пути, вы обнаружите все замечательные вещи, которые дает вам Bash , которые не доступны напрямую из Process.exec
(каналы, перенаправление, составные команды, расширение переменных , арифметическое вычисление, ...).
|
символов. Обязательно следите за ||
и строками в кавычках. процесс
для каждой переданной команды. поток
, который считывает вывод одной команды и записывает его на ввод следующей команды.