2010-02-05 13 views
7

Sto cercando di verificare la presenza di un tag SVN da uno script Perl. Così provo a chiamare svn info $url, leggere il codice di uscita e sopprimere l'output standard e gli stream di errore standard. Tuttavia, faccio fatica a fare questo con eleganza (ci sono modi probabilmente meglio chiedere SVN su un tag, ma non è questo il punto qui):Come si esegue uno script esterno mentre si acquisiscono sia il codice di uscita che quello di uscita in Perl?

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

Questa sopprime l'uscita, mentre la messa in $output. Il codice di uscita è perso.

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

Questo sopprime sia STDERR e STDOUT e li mette in entrambi $output. Il codice di uscita è di nuovo perso.

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

Questo preleva il codice di uscita, ma l'output effettivo e il flusso di errori sono visibili all'utente.

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

Questo uccide la STDOUT e STDERR e le catture il codice di uscita, ma è brutto, perché avrei dovuto per ricordare per commutare lo STDOUT Torna all'originale.

Quindi, c'è una soluzione più elegante?

risposta

8

Provare a utilizzare $? .e.g.

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

+2

Il codice di uscita è il byte alto in '$?', Quindi è necessario '$? >> 8'. –

+0

@brian: grazie per averlo indicato. – bhups

+1

Questo è stato un po 'spiacevole per voi per modificare la tua risposta. :) –

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

Questo sopprime sia STDERR e STDOUT e li mette in entrambi $ output. Il codice di uscita è di nuovo perso

Sei sicuro che il codice di uscita è stato perso? Quando provo questo, ottengo il codice di uscita in $?.

+0

Bene, il codice di uscita è il byte alto in '$?', Quindi è necessario '$? >> 8'. –

3

Cosa succede quando lo provi con IPC::System::Simple? Questo modulo gestisce la maggior parte dei dettagli di questi tipi di problemi:

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

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

Il modulo IPC::Run3 dà il controllo a grana molto fine sopra l'ingresso e l'uscita.

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

È possibile passare la stessa variabile per \$out e \$err e farà quello che vi aspettate, che unisce entrambi i flussi. L'ingresso non è necessaria, e così si può passare sia undef ("ereditare da processo padre") o \undef ("filehandle chiuso".)

IPC::Run3::run3() restituisce vero o falso a seconda del codice di uscita, e lascia il codice di uscita effettivo del processo figlio in $? come perlvar.

Nel tuo caso si correrebbe

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

Il valore restituito da run3 riguarda solo la gestione dei filehandle. Non ha senso per il codice di uscita del processo. –

Problemi correlati