7

Perl スクリプトから SVN タグの存在を確認しようとしています。そこで、 を呼び出し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 が強制終了され、終了コードがキャッチされますが、STDOUT を元の状態に戻すには覚えておく必要があるため、見苦しいものです。

それで、もっとエレガントな解決策はありますか?

4

4 に答える 4

8

$?.egを使用してみてください

my $output = `svn info $url/tags/$tag`;
my $extcode = $?>>8;

于 2010-02-05T09:33:06.543 に答える
3

IPC::System::Simpleで試してみるとどうなりますか? そのモジュールは、これらの種類の問題の詳細のほとんどを処理します。

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

 my $output = capturex( "some_command", @args );
 my $exit   = $EXITVAL;
于 2010-02-05T11:10:58.910 に答える
1
 my $output = `svn info $url/tags/$tag 2>&1`;

これにより、STDERR と STDOUT の両方が抑制され、両方が $output に入れられます。終了コードが再び失われる

終了コードが失われていますか? これを試すと、終了コードが に表示され$?ます。

于 2010-02-05T09:45:49.513 に答える
0

モジュールIPC::Run3は、入力と出力を非常にきめ細かく制御します。

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

同じ変数を\$outandに渡す\$errと、両方のストリームを組み合わせて、期待どおりの結果が得られます。入力は不要なので、undef("inherit from parent process") または\undef("closed filehandle".)のいずれかを渡すことができます。

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: $@";
}
于 2010-02-05T11:23:27.900 に答える