2013-07-08 11 views
9

codice nome del filedifferenza tra ./test.pl e perl test.pl

#!/usr/bin/perl -I/root/Lib/ 
use Data::Dumper; 
print Dumper \@INC; 

Il codice di cui sopra è test.pl e il permesso è 755.

Quando sto facendo funzionare il programma utilizzando/usr/bin/perl test.pl l'output di @INC contiene "/ root/Lib" alla fine. È come premere su @INC.

/usr/bin/perl test.pl uscita

$VAR1 = [ 
      '/etc/perl', 
      '/usr/local/lib/perl/5.10.0', 
      '/usr/local/share/perl/5.10.0', 
      '/usr/lib/perl5', 
      '/usr/share/perl5', 
      '/usr/lib/perl/5.10', 
      '/usr/share/perl/5.10', 
      '/usr/local/lib/site_perl', 
      '.', 
      '/root/Lib/' 
     ]; 

Ma quando sto facendo funzionare il programma utilizzando ./test.pl l'uscita del @INC contenere "/ root/lib /" contengono primo così come anche la fine. È come unshift e push.

uscita ./test.pl

$VAR1 = [ 
      '/root/Lib/', 
      '/etc/perl', 
      '/usr/local/lib/perl/5.10.0', 
      '/usr/local/share/perl/5.10.0', 
      '/usr/lib/perl5', 
      '/usr/share/perl5', 
      '/usr/lib/perl/5.10', 
      '/usr/share/perl/5.10', 
      '/usr/local/lib/site_perl', 
      '.', 
      '/root/Lib/' 
     ]; 

quindi voglio sapere che cosa è la differenza tra ./test.pl e/usr/bin/perl test.pl?

+0

+1 è un comportamento sorprendente, investigando ... – msw

+4

se hai fatto perl -I/root/Lib test.pl sarebbe lo stesso. Lo shebang sulla linea uno è usato come comando quando lo fai ./test.pl – KeepCalmAndCarryOn

+1

Curioso e curioso: se 'L' è'/root/lib' ottengo l'output di 'L, L, ...' per lo shebang esecuzione e 'L, ...' per l'invocazione/usr/bin/perl. Quale sistema operativo e (se applicabile) pacchetto Perl stai usando? – msw

risposta

6

Ci sono due domande in agguato qui. La domanda principale è "Qual è la differenza tra ./test.pl e perl test.pl?", Mentre la domanda secondaria è "Perché @INC viene aggiunto @INC quando lo script viene eseguito come ./test.pl e non quando viene eseguito come perl test.pl?"

una risposta, non necessariamente applicabile alla vostra situazione, è che ./test.pl corre l'interprete Perl specificata dalla baracca (/usr/bin/perl), mentre perl test.pl piste qualunque interprete Perl si trova prima a $PATH (o alias o funzioni). Non è necessario che siano la stessa versione di Perl. Per me, raramente sono la stessa versione di Perl; quello in /usr/bin è in genere relativamente vecchio e quello sul mio $PATH è relativamente nuovo (5.8.x contro 5.18.x, ad esempio).

Lavorare con Perl 5.12.4 (ahi, che è vecchio) da /usr/bin sulla mia macchina, e l'utilizzo di script, vedo:

$ perl test.pl 
$VAR1 = [ 
      '/root/Lib/', 
      '/Library/Perl/5.12/darwin-thread-multi-2level', 
      '/Library/Perl/5.12', 
      '/Network/Library/Perl/5.12/darwin-thread-multi-2level', 
      '/Network/Library/Perl/5.12', 
      '/Library/Perl/Updates/5.12.4', 
      '/System/Library/Perl/5.12/darwin-thread-multi-2level', 
      '/System/Library/Perl/5.12', 
      '/System/Library/Perl/Extras/5.12/darwin-thread-multi-2level', 
      '/System/Library/Perl/Extras/5.12', 
      '.' 
     ]; 
$ ./test.pl 
$VAR1 = [ 
      '/root/Lib/', 
      '/root/Lib/', 
      '/Library/Perl/5.12/darwin-thread-multi-2level', 
      '/Library/Perl/5.12', 
      '/Network/Library/Perl/5.12/darwin-thread-multi-2level', 
      '/Network/Library/Perl/5.12', 
      '/Library/Perl/Updates/5.12.4', 
      '/System/Library/Perl/5.12/darwin-thread-multi-2level', 
      '/System/Library/Perl/5.12', 
      '/System/Library/Perl/Extras/5.12/darwin-thread-multi-2level', 
      '/System/Library/Perl/Extras/5.12', 
      '.' 
     ]; 
$ 

noti che qui è aggiunto il nome /root/Lib una o due volte al @INC . La mia ipotesi migliore è che quando si utilizza perl test.pl, Perl analizza lo shebang e aggiunge l'opzione -I se trova lì. Quando si utilizza ./test.pl, il kernel viene eseguito /usr/bin/perl -I/root/Lib test.pl (in cui è possibile negoziare se il nomeviene visualizzato sulla riga di comando, il punto chiave è che appare -I/root/Lib), quindi Perl aggiunge /root/Lib una volta a causa dell'esplicita -I fornita dal kernel e quindi aggiunge un altro perché analizza la riga shebang.

Vedere: perldoc perlrun per molti altri dettagli.

2

Quando lo si esegue come perl test.pl, tra le prime cose che fa è vedere se c'è una riga che inizia con #!.Se ne trova uno cerca di comportarsi come se fosse chiamato con quegli argomenti.

Così il seguente aggiunge avvertenze

#! perl -w 

Se si esegue come ./test.pl il sistema in realtà lo gestisce con tali argomenti. Perl davvero non ha modo di sapere che è stato chiamato implicitamente così. Quindi Perl analizza solo quella linea come prima.

Nel tuo caso, ciò significa che /root/Lib/ verrà aggiunto a @INC due volte.

Il motivo appare all'inizio della lista; è che quando Perl viene effettivamente chiamato con quell'opzione, lo aggiunge prima che abbia la possibilità di caricare '@INC con qualcosa.
Se viene aggiunto durante l'analisi di #!, ha già inserito @INC in modo che venga aggiunto alla fine.

Problemi correlati