2013-07-08 15 views
9

Kod Nazwa plikuróżnica między ./test.pl i Perl test.pl

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

Powyższy kod jest test.pl a uprawnienie to 755.

Kiedy używam programu używając/usr/bin/perl test.pl plik wyjściowy @INC zawiera "/ root/Lib" na końcu. To jest jak wejście do @INC.

/usr/bin/perl test.pl Wyjście

$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/' 
     ]; 

Ale kiedy używam programu za pomocą ./test.pl wyjście @ INC zawiera "/ root/lib /" zawiera pierwszy a także koniec. To jest jak niezmienne i pchnięcie.

./test.pl wyjście

$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/' 
     ]; 

Więc chcę wiedzieć, jaka jest różnica między ./test.pl i/usr/bin/perl test.pl?

+0

+1 to zaskakujące zachowanie, badanie ... – msw

+4

jeśli zrobiłeś perl -I/root/Lib test.pl to byłoby tak samo. Shebang na linii 1 jest używany jako polecenie, gdy robisz ./test.pl – KeepCalmAndCarryOn

+1

Curiouser i curiouser: jeśli 'L' to'/root/lib', otrzymuję wyjście 'L, L, ...' dla shebangu wykonanie i 'L, ...' dla wywołania/usr/bin/perl. Jakiego systemu operacyjnego i (jeśli dotyczy) pakietu perlowego używasz? – msw

Odpowiedz

6

Istnieją dwa pytania czai tutaj. Najważniejsze pytanie brzmi: "Jaka jest różnica między ./test.pl i perl test.pl?", Podczas gdy pytanie dodatkowe brzmi "Dlaczegojest dodane z przodu @INC, gdy skrypt jest uruchamiany jako ./test.pl, a nie po uruchomieniu jako perl test.pl?"

odpowiedź, niekoniecznie mających zastosowanie do danej sytuacji jest to, że ./test.pl uruchamia interpreter Perla określony przez shebang (/usr/bin/perl), natomiast perl test.pl tras cokolwiek Perl interpreter znajdując najpierw na swoim $PATH (lub aliasów lub funkcji). Nie musi to być ta sama wersja Perla. Dla mnie bardzo rzadko są one tej samej wersji Perla; ten w /usr/bin jest zwykle względnie stary, a ten na moim $PATH jest stosunkowo nowy (na przykład 5.8.x vs 5.18.x).

Praca z Perl 5.12.4 (ouch, to jest stary) z /usr/bin na moim komputerze, a przy użyciu skryptu, widzę:

$ 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', 
      '.' 
     ]; 
$ 

Zauważ, że tutaj nazwa /root/Lib dodaje się raz lub dwa razy do @INC . Domyślam się, że podczas korzystania z perl test.pl, Perl skanuje shebang i dodaje opcję -I, jeśli znajdzie tam. Kiedy używasz ./test.pl, jądro działa /usr/bin/perl -I/root/Lib test.pl (gdzie możemy negocjować, czy nazwa test.pl pojawia się w linii poleceń, kluczowym punktem jest, że pojawia się -I/root/Lib), więc Perl dodaje /root/Lib raz z powodu jawnej -I dostarczonej przez jądro , a następnie dodaje kolejne, ponieważ analizuje linię półksiężyca.

Zobacz: perldoc perlrun po więcej szczegółów.

2

Po uruchomieniu go jako perl test.pl, wśród pierwszych rzeczy, które robi, jest sprawdzenie, czy istnieje linia zaczynająca się od #!.Jeśli znajdzie, spróbuje zadziałać tak, jakby zostało wywołane z tymi argumentami.

Więc dodaje się następujące ostrzeżenia

#! perl -w 

przypadku uruchomienia go jako ./test.pl system faktycznie działa to z tymi argumentami. Perl naprawdę nie ma sposobu, aby wiedzieć, że został tak zwany niejawnie. Tak więc Perl sam parsuje tę linię, tak jak poprzednio.

W twoim przypadku oznacza to, że /root/Lib/ zostanie dodany do @INC dwa razy.

Powód, dla którego pojawia się na początku listy; jest to, że kiedy Perl jest rzeczywiście wywoływany z tą opcją, dodaje ją, zanim będzie miał możliwość załadowania '@INC z niczym.
Jeśli zostanie dodany podczas analizowania #!, już zapełnił on @INC, więc dodaje go na końcu.