2016-03-21 12 views
14

Quando eseguo le chiamate system() in Perl, di solito ispeziono il codice di ritorno in base allo perldocs. Beh, l'ho pensato. La maggior parte delle volte $rc!=0 è sufficiente per me. Recentemente ho aiutato due persone qui che hanno avuto problemi con le chiamate system() quando eseguivano i loro script .cgi sotto apache. Li ho incaricato di esaminare la $rc di

my $rc = system(...); 

e li legati alla system() documenti. Poi ho guardato più da vicino e ho notato i documenti non sono realmente parlando del $rc ma invece circa $? e mi sentivo un po 'imbarazzato e la seguente questione è stata sollevata:

C'è una differenza tra:

system(...); 
if ($? == -1) { 
    print "failed to execute: $!\n"; 
} 
elsif ($? & 127) { 
    printf "child died with signal %d, %s coredump\n", 
     ($? & 127), ($? & 128) ? 'with' : 'without'; 
} 
else { 
    printf "child exited with value %d\n", $? >> 8; 
} 

e

my $rc = system(...); 
if ($rc == -1) { 
    print "failed to execute: $!\n"; 
} 
elsif ($rc & 127) { 
    printf "child died with signal %d, %s coredump\n", 
     ($rc & 127), ($rc & 128) ? 'with' : 'without'; 
} 
else { 
    printf "child exited with value %d\n", $rc >> 8; 
} 

Oppure, in breve, è pari a $rc$? per system()?

Ho controllato i documenti di system, wait e $? ma non è abbastanza chiaro per me. Ho sbagliato negli ultimi 15 anni usando $rc?

+1

Se si cattura il risultato a '$ rc' non c'è alcuna possibilità di' $ 'cambiare su di te prima di andare in giro a? usando quel valore. – tadman

+0

Grazie a @tadman. Ho aggiunto un commento alla risposta accettata che si applica anche al tuo commento. Usare '$ rc' sembra il modo più pulito per me. – PerlDuck

risposta

10

Sì, il valore restituito di systemcorrisponde a uguale a $?.

Tuttavia poiché $? non solo applicano alle chiamate e system$? è una variabile globale, potrebbe essere sovrascritta da altre azioni che si verificano. Da perldoc -v '$?' questi includono:

$ CHILD_ERROR

$?

Lo stato restituito dall'ultimo comando pipe close, backtick ("` `"), chiamata riuscita a "wait()" o "waitpid()" o dall'operatore "system()".

E 'molto più sicuro per memorizzare il valore immediatamente quindi confrontare:

my $rc = system('ls myfile.txt'); 
if ($rc >> 8 != 0) { 
    # do something because ls exited with an error 
} 
+0

Ottimo! Questo è quello che volevo sentire e assicurarmi. Grazie. Sono consapevole della volatilità di '$?' '(Come errno in C) e la uso solo se non sono disponibili $ rc espliciti (come con i backtick). Preferisco comunque i vars espliciti ed evito anche '$ _' quando possibile. La leggibilità e la manutenibilità dell'IMHO risentono dell'uso di troppe _magic_ vars. Quindi rimarrò con '$ rc'. :-) – PerlDuck

+2

'$?' È praticamente uguale al venerabile 'errno' di C, il che significa che ha molti degli stessi problemi. Le variabili globali magiche sembravano una buona idea una volta, ma per fortuna siamo andati avanti. – tadman

+3

@tadman In realtà, '$!' È praticamente lo stesso di 'errno' (recupera semplicemente il valore corrente di' errno'). '$?'è leggermente diverso perché viene impostato da ogni 'wait' o pipe close, anche se hanno successo (' $! 'è valido solo immediatamente dopo un errore). Ma hai ragione riguardo alle variabili globali. – ThisSuitIsBlackNot

Problemi correlati