Захват стандартного вывода при вызове Runtime.exec
При возникновении сетевых проблем на клиентских компьютерах я хотел бы иметь возможность запускать несколько командных строк и отправлять их результаты самому себе по электронной почте.
Я обнаружил, что Runtime.exec позволит мне выполнять произвольные команды, но собирать результаты в строку интереснее.
Я понимаю, что мог бы перенаправить вывод в файл, а затем прочитать из файла, но мое чутье подсказывает мне, что есть более элегантный способ сделать это.
Предложения?
Переведено автоматически
Ответ 1
Вам необходимо зафиксировать как std out, так и std err в процессе. Затем вы можете записать std out в файл / почту или что-то подобное.
Смотрите Эту статью для получения дополнительной информации и, в частности, обратите внимание на StreamGobbler механизм, который фиксирует стандартный вывод / ошибку в отдельных потоках. Это важно для предотвращения блокировки и является источником многочисленных ошибок, если вы не делаете это должным образом!
Ответ 2
Используйте ProcessBuilder. После вызова start() вы получите объект Process, из которого вы можете получить потоки stderr и stdout.
ОБНОВЛЕНИЕ: ProcessBuilder дает вам больше контроля; Вам не обязательно его использовать, но я нахожу это проще в долгосрочной перспективе. Особенно важна возможность перенаправлять stderr в стандартный вывод, что означает, что вам нужно отсосать только один поток.
Ответ 3
Для процессов, которые не генерируют много выходных данных, я думаю, этого простого решения, использующего Apache IOUtils, достаточно:
Предостережение: Однако, если ваш процесс генерирует много выходных данных, этот подход может вызвать проблемы, как упомянуто в классе процесса JavaDoc:
Созданный подпроцесс не имеет собственного терминала или консоли. Все его стандартные операции ввода-вывода (т.Е. stdin, stdout, stderr) будут перенаправлены родительскому процессу через три потока (getOutputStream(), getInputStream(), getErrorStream()). Родительский процесс использует эти потоки для передачи входных данных в подпроцесс и получения выходных данных из него. Поскольку некоторые собственные платформы предоставляют ограниченный размер буфера только для стандартных потоков ввода и вывода, неспособность своевременно записать входной поток или прочитать выходной поток подпроцесса может привести к блокировке подпроцесса и даже взаимоблокировке.
Ответ 4
Используйте Plexus Utils, он используется Maven для выполнения всех внешних процессов.