Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

difference between ./test.pl and perl test.pl

Tags:

linux

perl

Code

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

The above code file name is test.pl and the permission is 755.

When I am running the program using /usr/bin/perl test.pl the output of the @INC contains "/root/Lib" at the end. It is like push in to @INC.

/usr/bin/perl test.pl Output

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

But when I am running the program using ./test.pl the output of the @INC contain "/root/Lib/" contain first as well as end also. It is like unshift and push.

./test.pl output

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

So I want to know what is the difference between ./test.pl and /usr/bin/perl test.pl ?

like image 215
muruga Avatar asked Jul 08 '13 11:07

muruga


3 Answers

There are two questions lurking here. The headline question is "What's the difference between ./test.pl and perl test.pl?", while the secondary question is "Why is /root/Lib added at the front of @INC when the script is run as ./test.pl and not when run as perl test.pl?"

An answer, not necessarily applicable to your situation, is that ./test.pl runs the Perl interpreter specified by the shebang (/usr/bin/perl), whereas perl test.pl runs whatever Perl interpreter is found first on your $PATH (or aliases or functions). These need not be the same version of Perl. For me, they very seldom are the same version of Perl; the one in /usr/bin is usually relatively old and the one on my $PATH is relatively new (5.8.x vs 5.18.x, for example).

Working with Perl 5.12.4 (ouch; that's old) from /usr/bin on my machine, and using your script, I see:

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

Note that here the /root/Lib name is added once or twice to @INC. My best guess is that when you use perl test.pl, Perl scans the shebang and adds the -I option if finds there. When you use ./test.pl, the kernel runs /usr/bin/perl -I/root/Lib test.pl (where we can negotiation on whether the name test.pl appears on the command line; the key point is that the -I/root/Lib does appear), so Perl adds /root/Lib once because of the explicit -I provided by the kernel, and then adds another because it parses the shebang line.

See: perldoc perlrun for many more details.

like image 53
Jonathan Leffler Avatar answered Nov 14 '22 22:11

Jonathan Leffler


You should use lib instead. That way, execution is consistent.

#!/usr/bin/perl

use lib qw( /root/Lib/ );

use Data::Dumper;
print Dumper \@INC; 

See http://perldoc.perl.org/lib.html

like image 32
shawnhcorey Avatar answered Nov 14 '22 21:11

shawnhcorey


When you run it as perl test.pl, among the first things it does is look to see if there is a line starting with #!. If it finds one it tries to act as if it were called with those arguments.

So the following adds warnings

#! perl -w

If you run it as ./test.pl your system actually runs it with those arguments. Perl really doesn't have a way of knowing that it was called implicitly like that. So Perl just parses that line itself like it did previously.

In your case that means that /root/Lib/ will be added to @INC twice.

The reason it appears at the beginning of the list; is that when Perl is actually called with that option, it adds it before it has a chance to load '@INC with anything.
If it gets added when parsing #!, it has already populated @INC so it adds it at the end.

like image 2
Brad Gilbert Avatar answered Nov 14 '22 23:11

Brad Gilbert