Должностное лицо Java () не возвращает ожидаемый результат связанных команд каналов

Я называю программы командной строки соединенными каналами. Все это работает над 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))}

метод возвратит пустой указатель. Я предполагаю, что эта проблема зависит от выходных команд форматирования как голова, хвост, туалет, и т.д. Как я могу работать вокруг этой проблемы и получить конечный результат вывода?

6
задан Carl Manaster 18 January 2010 в 22:44
поделиться

5 ответов

До сих пор не нашла правильное решение для выполнения командных команд с помощью Runtime.exec, но нашел обходной путь. Я просто написал эти сценарии для разделения файлов Bash. Затем Runtime.exec вызывает эти сценарии Bash и получают ожидаемый результат.

2
ответ дан 8 December 2019 в 18:36
поделиться

Каждый, кто использует Runtime.exec, должен прочитать это .

2
ответ дан 8 December 2019 в 18:36
поделиться

Это может быть хорошая идея проверить поток ошибок процесса .

1
ответ дан 8 December 2019 в 18:36
поделиться

Труба (например, перенаправление или > ) является функцией оболочки, и поэтому выполнение непосредственно от Java не будет работать. Вам нужно сделать что-то вроде:

/bin/sh -c "your | piped | commands | here"

, который выполняет процесс оболочки с помощью командной строки (включая трубы), указанные после -C (в цитатах).

Обратите внимание, что необходимо употреблять STDOUT и STDERR одновременно , в противном случае ваш выреченный процесс будет блокировать ожидание вашего процесса, чтобы потреблять вывод (или ошибки). Больше информации здесь .

8
ответ дан 8 December 2019 в 18:36
поделиться

Быстрая и грязная вещь, которую нужно сделать:

command = "/bin/sh -c '" + command.replaceAll("'", "'\''") + "'"

Обычно вам нужно следить за инъекцией оболочки (т.е. кто-то крадется "; rm -rf /;" в команду). Но это проблема только в том случае, если часть команды может быть предоставлена ​​другим пользователем.

Медленным и болезненным подходом было бы самому сделать конвейер Bash на Java. Если вы пойдете по этому пути, вы обнаружите все замечательные вещи, которые дает вам Bash , которые не доступны напрямую из Process.exec (каналы, перенаправление, составные команды, расширение переменных , арифметическое вычисление, ...).

  1. Разберите команду на наличие | символов. Обязательно следите за || и строками в кавычках.
  2. Создать новый процесс для каждой переданной команды.
  3. Создайте поток , который считывает вывод одной команды и записывает его на ввод следующей команды.
0
ответ дан 8 December 2019 в 18:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: