我在perl脚本中使用了perl模块文件:
printtab.pl
use Table;
Table.pm
与printtab.pl
位于同一目录中,因此只要我从目录执行printtab,它就会正常运行。
但是如果我从其他地方执行它,例如,使用cronjob,我会收到一个错误,提到在@INC
中找不到该模块。
解决此问题的正确方法是什么?
我试过
push @INC, "/path/Table.pm";
但它不起作用。 你能告诉我为什么吗?
我发现了use lib
并且它可以正常工作
use lib "/path";
在这种情况下使用lib是最好的方法吗?
答案 0 :(得分:14)
use lib
是个不错的选择。但是,您是否将模块放在与程序相同的目录中(或相对于包含程序的子目录),您可以使用use FindBin;
之类的:
use FindBin;
use lib "$FindBin::Bin/../lib";
答案 1 :(得分:4)
push @INC, "/path/Table.pm";
不起作用,因为@INC应该是目录列表,而不是模块的完整路径。所以如果你这样做:
push @INC, "/path";
它应该有用。
话虽如此,use lib "/path";
也是一个不错的选择。
根据您的程序的安装目录结构,使用FindBin来确定脚本的真实位置可能对构建模块的正确路径有用。
答案 2 :(得分:1)
一个巧妙的小技巧:
#! /usr/bin/env perl
use strict;
use warnings;
BEGIN {
our $moduleIsMissing;
eval {
require My::Module;
};
if ($@) {
$moduleIsMissing = 1;
}
}
if ($main::moduleIsMissing) {
print "Module is missing. I've got to do something about it!\n"
}
else {
print "Module is there. I'm fine!\n";
}
我对$main::moduleIsMissing
事情感到不满意,但我还没有找到解决方法。
如果My::Module
可用,则已加载,一切正常。否则,设置$main::moduleIsMissing
标志。这允许您测试模块是否已加载,如果没有,则采取规避行动。例如,如果模块Term::Cap
可用,您的程序将在打印文本时使用粗体表面,但如果没有,则只打印出粗体字的文本。
回到问题:这样做要好得多:
use lib "MyDir";
而不是@INC
。
use lib
包括编译时的目录。因此,如果我在目录“MyDir”中有一个模块“Foo :: Bar”,我可以这样做:
use lib qw(MyDir);
use Foo::Bar;
没有Perl抱怨。如果我这样做了:
push (@INC, qw(MyDir));
use Foo::Bar;;
Perl会抱怨它无法找到我的模块。