Как я могу прочитать stderr, когда выполнение команды не удается в Perl? - PullRequest
3 голосов
/ 19 ноября 2008

Я выполняю команду diff в perl.

my @lines = `/usr/local/bin/diff -udr \"$expected_file\" \"$gen_file\"`;

if ($? != 0)
{
    print ERRFILE "Diff between $expected_file and $gen_file failed\n";
    return $diff_err;
}

Здесь diff мог произойти сбой по какой-то причине. Например: stderr показал, что / usr / local / bin / diff: test.txt: такого файла или каталога нет . Я хочу прочитать это сообщение в программе. Как мне найти сообщение stderr команды diff (или grep, или любую команду, которую я выполняю)?

Заранее признателен за помощь.

Спасибо, Мэтью Лию

Ответы [ 2 ]

12 голосов
/ 19 ноября 2008

Ответ на этот вопрос в perlfaq8: как мне захватить STDERR из внешней команды?

Если я хочу прочитать STDOUT и STDERR процесса, я использую IPC :: Open3, который поставляется с Perl. Таким образом, мне не нужно объединять эти потоки, а потом выяснить, какая часть вывода получена из чего.

Я бы старался по возможности избегать временных файлов (поэтому нет 2>file.txt). Это просто слишком много работы и кода, когда я могу читать STDERR напрямую.

4 голосов
/ 19 ноября 2008

Существует несколько модулей CPAN, которые облегчают эту задачу и позволяют разделить STDOUT и STDERR. Например, IO :: CaptureOutput позволит вам сделать это следующим образом (хотя вам нужно будет разделить строки самостоятельно):

use IO::CaptureOutput 'qxx';


my ($stdout, $stderr, $ok) = 
    qxx( qq(/usr/local/bin/diff -udr "$expected_file" "$gen_file") );

if (! $ok)
{
    print ERRFILE "Diff between $expected_file and $gen_file failed\n";
    return $stderr;
}

my @lines = split /\n/, $stdout;

- Дэвид

...