9

代码

#!/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/”,其中包含 first 以及 end。这就像 unshift 和 push。

./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 有什么区别?

4

3 回答 3

7

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

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

在我的机器上使用 Perl 5.12.4(哎呀;那是旧的)/usr/bin,并使用您的脚本,我看到:

$ 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了解更多详细信息。

于 2013-07-08T16:55:17.113 回答
2

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

#!/usr/bin/perl

use lib qw( /root/Lib/ );

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

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

于 2013-07-08T14:30:16.913 回答
2

当您运行它时perl test.pl,它首先要做的就是查看是否有以 . 开头的行#!。如果它找到一个,它会尝试像使用这些参数调用它一样行事。

所以以下添加警告

#! perl -w

如果您在./test.pl系统实际运行时使用这些参数运行它。Perl 真的没有办法知道它是这样被隐式调用的。所以 Perl 只是像以前一样解析该行本身。

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

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

于 2013-07-15T13:38:25.693 回答