2010-02-05 5 views
7

Ich versuche, nach einem SVN-Tag Existenz von einem Perl-Skript zu überprüfen. Also versuche ich svn info $url aufrufen, Exit-Code lesen und Standard-Ausgabe und Standard-Fehler-Streams zu unterdrücken. Aber ich kämpfe, dies zu tun elegant (es gibt wahrscheinlich bessere Möglichkeiten SVN über einen Tag zu fragen, aber das ist nicht der Punkt hier):Wie führe ich ein externes Skript aus, während ich sowohl den Ausgabe- als auch den Exit-Code in Perl aufzeichne?

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

Dadurch wird die Ausgabe unterdrückt, während es in $output setzen. Exit-Code ist verloren.

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

Dies unterdrückt sowohl STDERR und STDOUT und legt sie beide in $output. Exit-Code ist wieder verloren.

Dies fängt den Exit-Code ab, aber der tatsächliche Ausgabe- und Fehlerstrom ist für den Benutzer sichtbar.

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"; 

Dies tötet die STDOUT- und STDERR und fängt den Exit-Code, aber es ist hässlich, weil ich erinnere müsste die STDOUT- zurück zum Original zu wechseln.

Gibt es also eine elegantere Lösung?

Antwort

8

Versuchen Sie mit $?. Z.

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

+2

Der Exit-Code der High-Byte in '$ ist?', So dass Sie '$ benötigen? >> 8'. –

+0

@brian: danke für das hinweisend. – bhups

+1

Das war ein kleiner Anstoß für Sie, Ihre Antwort zu bearbeiten. :) –

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

Dies unterdrückt sowohl STDERR und STDOUT und legt sie beide in $ ausgegeben. Exit-Code ist wieder verloren

Sind Sie sicher, dass der Exit-Code verloren ist? Wenn ich das versuche, bekomme ich den Exit-Code in $?.

+0

Nun, der Exit-Code ist das High-Byte in '$?', Also brauchen Sie '$? >> 8'. –

3

Was passiert, wenn Sie es mit IPC::System::Simple versuchen? Das Modul übernimmt die meisten Details dieser Art von Problemen:

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

my $output = capturex("some_command", @args); 
my $exit = $EXITVAL; 
0

Das Modul IPC::Run3 gibt sehr feinkörnige Kontrolle über die Ein- und Ausgang.

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

Sie können die gleiche Variable \$out und \$err passieren und es wird tun, was Sie erwarten, beide Ströme zu kombinieren. Die Eingabe ist nicht notwendig, und so können Sie passieren entweder undef („erben von Eltern-Prozess“) oder \undef („closed Dateikennung“.)

IPC::Run3::run3() kehrt wahr oder falsch auf dem Exit-Code abhängig, und verläßt den tatsächlichen Exit-Code des Kinderprozesses in $? wie perlvar.

In Ihrem Fall würden laufen Sie

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: [email protected]"; 
} 
+0

Der Rückgabewert von run3 behandelt nur die Handhabung der Dateihandles. Es ist bedeutungslos für den Exit-Code des Prozesses. –