Как я выполняю внешний сценарий при получении и вывода и кода выхода в Perl?

Я пытаюсь проверить на существование тега SVN из сценария Perl. Таким образом, я пытаюсь звонить svn info $url, прочитайте код выхода и подавите потоки стандартной погрешности и стандартный вывод. Однако я изо всех сил пытаюсь сделать это изящно (существуют, вероятно, лучшие способы спросить SVN о теге, но это не точка здесь):

my $output = `svn info $url/tags/$tag`;

Это подавляет вывод при помещении его в $output. Код выхода потерян.

my $output = `svn info $url/tags/$tag 2>&1`;

Это подавляет и STDERR и STDOUT и помещает их обоих в $output. Код выхода снова потерян.

my $exitcode = system("svn", "info", "$url/tags/$tag");

Это ловит код выхода, но эффективная выходная мощность и поток сообщений об ошибках видимы пользователю.

open( STDERR, q{>}, "/dev/null" );
open my $fh, q{>}, "/dev/null";
select($fh);
if (system("svn", "info", "$url/tags/$tag") != 0) {
   select(STDOUT);
   print ("Tag doesn't exist!");
   do_something_with_exit();
}
select(STDOUT);
print "Exit code: $exitcode";

Это уничтожает STDOUT и STDERR и ловит код выхода, но это ужасно, потому что я имел бы к remeber для переключения STDOUT назад на оригинал.

Так, есть ли еще изящное решение?

7
задан brian d foy 5 February 2010 в 11:06
поделиться

4 ответа

Попробуйте использовать $? . Например.

my $output = `svn info $url/tags/$tag`;
my $extcode = $?>>8;
8
ответ дан 6 December 2019 в 21:13
поделиться
 my $output = `svn info $url/tags/$tag 2>&1`;

Это подавляет как STDERR, так и STDOUT и помещает их в $ output. Код выхода снова потерян

Вы уверены, что код выхода потерян? Когда я пробую это сделать, я получаю код выхода в $? .

1
ответ дан 6 December 2019 в 21:13
поделиться

Модуль IPC::Run3 дает очень тонкий контроль над входом и выходом.

use IPC::Run3;
run3 \@cmd, \$in, \$out, \$err;

Одну и ту же переменную можно передать в \$out и \$err, и он будет делать то, что вы ожидаете, объединяя оба потока. Вход не нужен, поэтому вы можете передать либо undef ("наследовать от родительского процесса"), либо \undef ("закрытый файловый хэндл")

IPC::Run3::run3() возвращает true или false в зависимости от кода выхода и оставляет действительный код выхода дочернего процесса в $? согласно 'perlvar'.

В вашем случае вы бы выполнили

use IPC::Run3

my @cmd = ('svn', 'info', "$url/tags/$tag");
my $out;
my $rv = run3(\@cmd, \undef, \$out, \$out);
if ($rv) {
    # process $out
}
else {
    die "error: $@";
}
0
ответ дан 6 December 2019 в 21:13
поделиться

Что произойдет, если вы попробуете его с IPC :: System :: Simple ? Этот модуль обрабатывает большую часть деталей такого рода проблем:

 use IPC::System::Simple qw(capturex $EXITVAL);

 my $output = capturex( "some_command", @args );
 my $exit   = $EXITVAL;
3
ответ дан 6 December 2019 в 21:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: