我有一个简单的Perl脚本,该脚本使用位于另一个文件中的辅助函数common.pl:
#!/usr/bin/perl
use strict;
use warnings;
use Cwd 'abs_path';
use File::Basename qw( fileparse );
use File::Path qw( make_path );
use File::Spec;
require "common.pl"; # line 15
#...
Run Code Online (Sandbox Code Playgroud)
#!/usr/bin/perl
use strict;
use warnings;
sub getTimeLoggerHelper{
#....
}
1;
Run Code Online (Sandbox Code Playgroud)
在本地,一切运行良好,但是当我尝试通过ssh运行它时,出现错误:
Can't locate common.pl in @INC (@INC contains:
/Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18
/Network/Library/Perl/5.18/darwin-thread-multi-2level
/Network/Library/Perl/5.18
/Library/Perl/Updates/5.18.2/darwin-thread-multi-2level
/Library/Perl/Updates/5.18.2
/System/Library/Perl/5.18/darwin-thread-multi-2level
/System/Library/Perl/5.18
/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.18 .) at /Users/snaggs/scripts/main.pl line 15.
Run Code Online (Sandbox Code Playgroud)
如果我登录到远程计算机并运行相同的脚本,则没有错误。
我也尝试转换common.pl为模块:
package Common;
use strict;
use warnings;
sub getTimeLoggerHelper{
#....
}
1;
__END__
Run Code Online (Sandbox Code Playgroud)
从main.pl我这样称呼它
use Module::Load;
load Common;
Run Code Online (Sandbox Code Playgroud)
相同的问题,本地工作,来自ssh-相同的错误:
Can't locate Common.pm in @INC (you may need to install the Common module)
Run Code Online (Sandbox Code Playgroud)
如何摆脱这个问题?
如果您需要使用require此方法,请提供完整路径
require "/full/path/to/common.pl";
Run Code Online (Sandbox Code Playgroud)
这是必要的了ssh,即使该文件是在同一目录,从此你.在@INC为没有脚本的目录(但有可能你的HOMEIS)。在其他情况下也会发生这种情况。
请注意,这种方式要导入的一切即是common.pl。
代替使用适当的模块有很多优点。然后,该文件为,.pm并且按照惯例,文件名被大写(并用驼峰大小写)。
这是带有文件bin/mail.pl和lib/Common.pm
bin / main.pl
use warnings;
use strict;
use FindBin qw($RealBin); # Directory in which the script lives
use lib "$RealBin/../lib"; # Where modules are, relative to $RealBin
use Common qw(test_me);
test_me();
Run Code Online (Sandbox Code Playgroud)
@INC使用lib pragma 完成设置的关键部分,即在其中寻找模块的地方。它将@INC在编译时将目录添加到default的开头。该FindBin的$RealBin是脚本的目录,与链接解决。我们使用它,以便添加的路径是相对于脚本而不是硬编码的。当脚本及其库合并在一起时,这有助于源组织。
另一种设置方法是通过环境变量PERL5LIB。用bash
export PERL5LIB=/path/to/libdir
Run Code Online (Sandbox Code Playgroud)
然后,对于其中Module.pm存在的内容,libdir您只需要说use Module就可以找到它。例如,这对于驻留在特定位置并被各种脚本使用的模块很有用。
lib / Common.pm
package Common;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT_OK = qw( test_me );
sub test_me { print "Hello from ", __PACKAGE__, "\n" }
1;
Run Code Online (Sandbox Code Playgroud)
当一个包是使用 ð它的文件是第一需要 d,然后模块的导入方法运行,在编译时。import调用者实际上是通过它获得模块中定义的符号(函数和变量的名称)的,我们必须import在模块中提供一个方法(或Module::function在调用者中使用标准名称)。
与线use Exporter带来的 import套路,所以我们没有写我们自己。在旧版的Exporter中,通常是通过继承使用的@ISA = ('Exporter')。参见文档。
然后,可通过使用符号@EXPORT_OK。这要求调用者列出要使用的功能。默认情况下,它不会将任何内容“推送”到其名称空间中。这也%EXPORT_TAG有帮助,特别是如果呼叫者导入的符号列表越来越长。