Как я могу запустить внешнюю команду и записать ее вывод в Perl?
Я новичок в Perl и хочу знать, как запустить внешнюю команду (назовите ее prg
) в следующих сценариях:
- Запустите
prg
, получите только stdout
.
- Запустите
prg
, выберите только stderr
.
- Запустите
prg
, добавьте его stdout
и stderr
, отдельно.
Ответы
Ответ 1
Вы можете использовать backtics для выполнения вашей внешней программы и захвата ее stdout
и stderr
.
По умолчанию обратные выходы отбрасывают stderr
и возвращают только stdout
внешней программы. Так
$output = `cmd`;
Захватит stdout
программы cmd и отбросит stderr
.
Чтобы записать только stderr
, вы можете использовать дескрипторы файла оболочки как:
$output = `cmd 2>&1 1>/dev/null`;
Для захвата как stdout
, так и stderr
вы можете сделать:
$output = `cmd 2>&1`;
Используя вышеизложенное, вы не сможете различать stderr
от stdout
. Чтобы separte stdout
из stderr
может перенаправить оба файла в отдельный файл и прочитать файлы:
`cmd 1>stdout.txt 2>stderr.txt`;
Ответ 2
Вы можете использовать IPC::Open3 или IPC::Run. Кроме того, прочитайте Как я могу захватить STDERR из внешней команды из perlfaq8.
Ответ 3
В большинстве случаев вы можете использовать оператор qx//
(или обратные ссылки). Он интерполирует строки и выполняет их с оболочкой, поэтому вы можете использовать перенаправления.
-
Для захвата команды STDOUT (STDERR не изменяется):
$output = `cmd`;
-
Чтобы захватить команду STDERR и STDOUT вместе:
$output = `cmd 2>&1`;
-
Чтобы захватить команду STDERR, но отбросить ее STDOUT (здесь важно упорядочить):
$output = `cmd 2>&1 1>/dev/null`;
-
Чтобы обменять команду STDOUT и STDERR, чтобы захватить STDERR, но оставить STDOUT для выхода из старого STDERR:
$output = `cmd 3>&1 1>&2 2>&3 3>&-`;
-
Чтобы прочитать как команду STDOUT, так и ее STDERR отдельно, проще всего перенаправить их отдельно к файлам, а затем прочитать из этих файлов, когда программа будет выполнена:
system("program args 1>program.stdout 2>program.stderr");