Как я могу запустить внешнюю команду и записать ее вывод в 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`;

Ответ 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");