无法在“要求”加载的@INC Perl perl文件中找到

sna*_*ggs 2 ssh perl

我有一个简单的Perl脚本,该脚本使用位于另一个文件中的辅助函数common.pl

main.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)

common.pl

#!/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)

[编辑1]

如果我登录到远程计算机并运行相同的脚本,则没有错误。

[编辑2]

我也尝试转换common.pl为模块:

common.pm

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)

如何摆脱这个问题?

zdi*_*dim 5

如果您需要使用require此方法,请提供完整路径

require "/full/path/to/common.pl";
Run Code Online (Sandbox Code Playgroud)

这是必要的了ssh,即使该文件是在同一目录,从此你.@INC没有脚本的目录(但有可能你的HOMEIS)。在其他情况下也会发生这种情况。

请注意,这种方式要导入的一切即是common.pl

代替使用适当的模块有很多优点。然后,该文件为,.pm并且按照惯例,文件名被大写(并用驼峰大小写)。

这是带有文件bin/mail.pllib/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有帮助,特别是如果呼叫者导入的符号列表越来越长。