之间的差异/test.pl和perltest.pl



代码

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

上面的代码文件名为test.pl,权限为755。

当我使用/usr/bin/perl-test.pl运行程序时,@INC的输出在末尾包含"/root/Lib"。这就像是向@INC推送。

/usr/bin/perl-test.pl输出

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

但是当我使用运行程序时/test.pl@INC的输出包含"/root/Lib/",包含第一个和最后一个。这就像松开和推。

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

所以我想知道两者之间的区别/test.pl和/usr/bin/perl-test.pl?

这里隐藏着两个问题。标题问题是"./test.plperl test.pl之间有什么区别?",而次要问题是"当脚本以./test.pl运行而不是以perl test.pl运行时,为什么在@INC的前面添加/root/Lib?"

一个不一定适用于您的情况的答案是,./test.pl运行shebang指定的Perl解释器(/usr/bin/perl),而perl test.pl运行首先在$PATH(或别名或函数)上找到的任何Perl解释器。这些不需要是相同版本的Perl。对我来说,它们很少是相同版本的Perl;/usr/bin中的一个通常相对较旧,而我的$PATH上的一个相对较新(例如,5.8.x对5.18.x)。

在我的机器上使用/usr/bin中的Perl5.12.4(ouch;这是旧的),并使用您的脚本,我看到:

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

注意,这里/root/Lib名称被添加到@INC一次或两次。我的最佳猜测是,当您使用perl test.pl时,Perl会扫描shebang,并在那里添加-I选项。当您使用./test.pl时,内核运行/usr/bin/perl -I/root/Lib test.pl(在这里我们可以协商名称test.pl是否出现在命令行上;关键是-I/root/Lib确实出现了),所以Perl添加了一次/root/Lib,因为内核提供了明确的-I,然后添加了另一个,因为它解析了shebang行。

有关更多详细信息,请参阅:perldoc perlrun

您应该改为use lib。这样,执行是一致的。

#!/usr/bin/perl
use lib qw( /root/Lib/ );
use Data::Dumper;
print Dumper @INC; 

请参阅http://perldoc.perl.org/lib.html

当您将其作为perl test.pl运行时,它所做的第一件事就是查看是否有一行以#!开头。如果它找到了一个,它会试图表现得像是被那些论点所召唤。

因此以下添加了警告

#! perl -w

如果您将其作为./test.pl运行,那么您的系统实际上会使用这些参数来运行它。Perl真的无法知道它是这样被隐式调用的。所以Perl只是像以前一样解析这一行。

在您的情况下,这意味着/root/Lib/将被添加到@INC中两次。

它出现在列表开头的原因;实际上,当使用该选项调用Perl时,它会在有机会用任何东西加载'@INC之前添加它
如果它在解析#!时被添加,那么它已经填充了@INC,所以它在最后添加它。

最新更新