2010-02-05 12 views
7

Próbuję sprawdzić istnienie znacznika SVN ze skryptu Perla. Więc próbuję wywoływać svn info $url, czytać kod wyjścia i tłumić standardowe wyjścia i standardowe strumienie błędów. Jednakże, walczę, aby to zrobić elegancko (prawdopodobnie istnieją lepsze sposoby, aby poprosić o znaczniku SVN, ale nie o to tu chodzi):Jak wykonać skrypt zewnętrzny podczas przechwytywania kodu wyjściowego i kodu wyjścia w Perlu?

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

ten hamuje wyjście podczas oddawania go do $output. Kod zakończenia jest utracony.

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

ten hamuje zarówno STDERR i stdout i umieszcza je zarówno do $output. Kod zakończenia jest ponownie utracony.

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

To przechwytuje kod wyjścia, ale rzeczywisty strumień danych wyjściowych i błędów jest widoczny dla użytkownika.

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

To zabija stdout i stderr i łapie kod wyjścia, ale jest brzydki, bo musiałbym zapamiętania, aby przełączyć stdout powrotem do oryginału.

Czy istnieje jakieś bardziej eleganckie rozwiązanie?

Odpowiedz

8

Spróbuj użyć $? .e.g.

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

+2

Kod zakończenia jest bajt w '$?', Więc trzeba '$? >> 8'. –

+0

@brian: dzięki za wskazanie tego. – bhups

+1

To było trochę zajęcie, aby edytować odpowiedź. :) –

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

ten hamuje zarówno STDERR i stdout i umieszcza je zarówno do $ wyjściu. Kod zakończenia jest ponownie utracony

Czy na pewno utracono kod zakończenia? Kiedy próbuję tego, otrzymuję kod wyjścia w $?.

+0

Kod wyjścia to wysoki bajt w '$?', Więc potrzebujesz '$? >> 8'. –

3

Co stanie się, gdy spróbujesz z IPC::System::Simple? Że moduł obsługuje większość szczegółów tego rodzaju problemów:

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

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

Moduł IPC::Run3 daje bardzo precyzyjną kontrolę nad wejściem i wyjściem.

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

można przekazać tę samą zmienną \$out i \$err i będzie robić to, czego oczekują, łącząc oba strumienie. Wejście jest zbędne, a więc można przejść albo undef („dziedziczą z procesu macierzystego”) lub \undef („zamknięte filehandle”).

IPC::Run3::run3() zwraca prawdę lub fałsz w zależności od kodu wyjścia i pozostawia rzeczywisty kod wyjścia procesu potomnego w $? według "perlvar".

W twoim przypadku byłoby uruchomić

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

Wartość zwracana z run3 dotyczy tylko obsługi uchwytów plików. Nie ma znaczenia dla kodu wyjścia procesu. –