2016-11-24 7 views
1

Я пытаюсь протестировать модуль Perl IPC :: Run3, но с трудностью проверить, была ли команда неудачной или успешной.
Я знаю, что IPC :: Run3 выдает код выхода, если что-то не так с его аргументами, но как насчет аргументов в порядке, но команда не существует? Как я могу проверить следующий пример?Как проверить статус выхода из IPC :: Run3

Имея подпрограмму для вызова RUN3

sub runRun3 { 

    my $cmd = shift; 
    my ($stdout, $stderr); 

    run3($cmd, \undef, \$stdout, \$stderr); 

# if($? == -1) { 
    if (! $stdout and ! $stderr) { 
     die "Something is wrong"; 
    } else { 
     print "OK \n"; 
    } 

} 

когда команда $cmds[0] ниже Выполняется (ls команда * NIX систем) печатает OK, как ожидалось, но с командой $cmds[1] он просто говорит No such file or directory at ./testrun3.pl line 18. С тестом на код выхода я хочу, чтобы он печатал Something is wrong.

#!/usr/bin/perl 

use warnings; 
use strict; 

use IPC::Run3; 

my @cmds = qw(ls silly); 

runRun3($cmds[0]); 
runRun3($cmds[1]); 

Или что было бы лучшей альтернативой IPC :: Run3 в таких случаях? Это просто упрощение процесса, но в конечном итоге я хотел бы зафиксировать STDERR и STDOUT для более сложных ситуаций.

Спасибо.

ответ

2

Несколько точек для прохождения.

Во-первых, за прямой вопрос, документация IPC::Run3 говорит нам, что

run3 бросает исключение, если завернуты system вызов возвращается -1 или что-то пошло не так с обработкой run3 «s из дескрипторов файлов. В противном случае он возвращает true. Он оставляет $? неповрежденным для проверки состояния выхода и ожидания.

ошибка вы спрашиваете о том такого рода, и вы должны eval вызов, чтобы поймать это исключение

use warnings 'all'; 
use strict; 
use feature 'say'; 

my ($stdout, $stderr); 

my @cmd = ("ls", "-l"); 

eval { run3 \@cmd, \undef, \$stdout, \$stderr }; 
if ([email protected]  ) { print "Error: [email protected]";      } 
elsif ($? & 0x7F) { say "Killed by signal ".($? & 0x7F); } 
elsif ($? >> 8 ) { say "Exited with error ".($? >> 8); } 
else    { say "Completed successfully";   } 

Теперь вы можете печатать свои собственные сообщения внутри if ([email protected]) { } блока, когда ошибки случаются, когда основной system не выполняется. Например, когда вызывается несуществующая программа.

Здесь [email protected] относится к eval, а $? - system. Так что если run3 не было проблемой, а [email protected] является ложным, мы проверяем статус system, таким образом $?. Из документации

Обратите внимание, что истинное значение, возвращаемое run3 не означает, что команда имела успешный код завершения. Следовательно, вы всегда должны проверить $?.

Для переменных [email protected] и $? см General Variables in perlvar и system и eval страниц.

Минимальная версия этого является падение eval[email protected] чека) и ожидать программу die если это run3 были проблемы, что должно быть редким, и проверить (и печать) значение $?.

Примечание: run3 Интерфейс. С \@cmd он ожидает, что @cmd содержит команду, разбитую на слова, первый элемент - это программа и остальные аргументы. Существует разница между написанием команды в строке, поддерживаемой интерфейсом $cmd, и в массиве. См. system для пояснения.

Какой вариант подойдет вам лучше всего, зависит от ваших конкретных потребностей. Вот несколько вариантов. Возможно, сначала попробуйте IPC::System::Simple (но нет STDERR на блюде). Для чистого захвата всех видов вывода Capture::Tiny отлично. На другом конце есть IPC::Run для большей мощности.

+0

@ikegami О, конечно, гораздо лучше показать все (и правильно). Спасибо. – zdim

 Смежные вопросы

  • Нет связанных вопросов^_^