2011-08-16 15 views
9

Sto usando Perl 5.10.1 su Ubuntu 11.04. Voglio che Perl esegua uno script di shell ed esca con lo stesso codice che chiude lo script della shell. Ma questo non sta funzionando per me ...Ottenere Perl per restituire il codice di uscita corretto

system($runCmd) or die("Failed to run \"$runCmd\": $!"); 

mi hanno confermato che l'esecuzione del "$ RunCmd" da solo restituisce un codice di uscita di 255, ma la clausola di "morire" non è sempre invocato. Come posso uscire con il codice corretto o almeno fallire per i codici non riusciti?

Un altro requisito minore è che voglio che l'output da $ runCmd venga stampato sullo schermo.

risposta

8

Come dice perldoc -f die, die non fornisce un codice di uscita specifico (solo un codice di uscita diverso da zero). Per ottenere ciò che si desidera, avrete bisogno di qualcosa di simile:

my $exit_code=system($runCmd); 

if($exit_code!=0) 
{ 
    print "Command $runCmd failed with an exit code of $exit_code.\n"; 
    exit($exit_code >> 8); 
} 
else 
{ 
    print "Command $runCmd successful!\n"; 
} 
+8

È necessario: 'exit ($ exit_code >> 8)'. – ErikR

+0

Perché, esattamente? –

+3

Il valore restituito da 'system()' è un numero intero che codifica il valore di uscita del processo figlio più indicatori che indicano come il processo figlio è terminato (terminazione normale, ucciso da un segnale, ecc.) Il valore passato a 'exit () 'è solo il valore di uscita. – ErikR

6

Se system restituisce 255, è necessario un and condizionale.

system restituisce zero su esecuzione riuscita. Inoltre, die modificherà il codice di uscita dello script. Invece warn e tornare l'ultimo codice di uscita in questo modo:

system($cmd) and do { 
    warn "Failed to run $cmd. Exit code is $?"; 
    exit $? >> 8; 
}; 

Per raggiungere l'output del programma, usare il backtick dell'operatore (`):

my $output = `$cmd`; 

if ($?) { 
    warn ...; 
    exit $? >> 8; 
} 

L'operatore backtick cattura solo STDOUT, quindi per tutti i messaggi di errore (che di solito vanno a STDERR) da catturare, modificare $cmd e aggiungere 2>&1 ad esso.

Si noti lo spostamento a sinistra di otto bit su $? globale.


crediti vanno a @musiKk: I perl documentation on system() stati come recuperare correttamente lo stato di uscita reale.

+3

Solo un'aggiunta: è necessario spostare il valore di ritorno di 'system' per otto a destra per ottenere il valore di ritorno di' $ cmd'. (http://perldoc.perl.org/functions/system.html) – musiKk

+0

Grazie, @musiKk. Ho aggiornato la mia risposta di conseguenza. –

4
system($runCmd) or die("Failed to run \"$runCmd\": $!"); 

A differenza di gran parte delle funzioni Perl, system restituisce false quando ha successo e vera quando non riesce. Questo è completamente indietro, lo so, ma è proprio così.

È necessario "system() e" not "system() o". E probabilmente vuoi lo $? non $!, anche se a volte questo può essere complicato.

Ho un avversione minore

system(...)       && die 

perché si avvita in su tutto il resto || die 's che normalmente fanno un continuo doppio margine verticale sopra a destra, a volte scrivere

system(...) == 0      || die 

in modo che vengano allineati correttamente di nuovo.

0

Se il sistema() s 'arretratezza apparente ti dà fastidio, si può sempre rendere più appetibile facendo qualcosa di simile:

my $err = system '/something/that/may/not/work'; 
if ($err) { 
    warn "@{[$! || 'undefined error']}\n"; 
    exit $err >> 8; 
} 

tuo $ RunCmd, BTW, se viene stampato sullo schermo (e questo è eseguito dalla riga di comando e non hai reindirizzato l'output, ecc.) verrà stampato sullo schermo. È solo che IT lo stamperà sullo schermo. Perl non sarà responsabile di ciò o saprà (o cura) cosa sta stampando. Se è tutto ciò che vuoi e non vuoi analizzare o manipolare sistematicamente l'output di $ runCmd, sei d'oro. Provalo:

perl -e "system 'ls -Fahl'" 

Inoltre, non interferirà nemmeno con lo STDOUT di $ runCmd. Andrà anche al tuo terminale. Ad esempio:

$ perl -e "system 'ls -Fahl /dev/null/something' and die qq(fail: $! >> 8 == @{[$! >> 8]})" 
ls: /dev/null/something: Not a directory 
fail: 26205 >> 8 == 102 at -e line 1. 
Problemi correlati