Я плохо знаком с Perl и хочу знать о способе работать, внешняя команда (назовите его prg
) в следующих сценариях:
prg
, получите stdout
только.prg
, получите stderr
только.prg
, получите stdout
и stderr
, отдельно. Вы можете использовать бэктики для выполнения вашей внешней программы и захвата ее 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
. Чтобы отделить stdout
от stderr
может перенаправить как в отдельный файл, так и прочитать файлы:
`cmd 1>stdout.txt 2>stderr.txt`;
В большинстве случаев вы можете использовать оператор 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");
Вы можете использовать IPC :: Open3 или IPC :: Run . Также прочтите Как захватить STDERR из внешней команды из perlfaq8 .