我们维护了大量的perl模块,实际上它非常庞大,我们甚至不知道我们负责的所有模块。我们希望跟踪哪些脚本和模块在某种日志中访问另一个模块,最好是按模块名称存储,这样我们就可以评估更新模块是否存在风险,以便我们知道可能会影响哪些模块。
有没有简单的方法可以做到这一点?
答案 0 :(得分:3)
您可以进行简单的正则表达式搜索:
use strict;
use warnings;
my %modules;
foreach my $perl_file (@file_list) {
open FILE, $perl_file or die "Can't open $perl_file ($!)";
while (<FILE>) {
if (/\s*(?:use|require)\s*([^;]+);/) {
$modules{$1}{$perl_file}++;
}
}
}
这很快又很脏,但它应该可以很好地工作。最后得到一个模块散列,每个模块都指向使用它的文件的散列。
当然,它会捕捉use strict;
之类的内容,但这些内容很容易被忽略。
如果你有像use Module qw/function/;
这样的东西你会在分号之前抓住整个东西,但这应该不是什么大问题。您只需搜索已知模块名称的键即可。
缺点是它不跟踪依赖性。如果您需要这些信息,可以通过从cpan或其他地方获取它来添加它。
更新:如果要在运行时记录此内容,可以创建一个包装器脚本,并让perl
命令指向系统上的包装器。然后使包装器像这样:
use strict;
use warnings;
use Module::Loaded;
my $script = shift @ARGV;
#run program
do $script;
#is_loaded() gets the path of these modules if they are loaded.
print is_loaded('Some::Module');
print is_loaded('Another::Module');
但是,您可能会冒着有趣的副作用,因为调用脚本的方法已经改变。这取决于你在做什么。
答案 1 :(得分:1)
也许编辑sitecustomize.pl以便每次Perl运行时,它会在日志中写入一些信息,然后进行分析?将这样的内容添加到sitecustomize.pl:
open (LOG, '>>',"absolutepathto/logfile.txt");
print LOG $0,"\t",$$,"\t",scalar(localtime),"\n";
open SELF, $0;
while (<SELF>) {
print LOG $_ if (/use|require/);
}
close SELF;
print LOG "_" x 80,"\n";
close LOG;
编辑: 另外,我们忘记了%INC哈希,所以上面的代码可以重写如下,以包含更多关于实际加载哪些模块的数据+包含do函数所需的文件:
open (LOG, '>>',"absolutepathto/logfile.txt");
print LOG $0,' ',$$,' ',scalar(localtime),"\n";
open SELF, $0;
while (<SELF>) {
print LOG $_ if (/use|require/);
}
close SELF;
END {
local $" = "\n";
print LOG "Files loaded by use, eval, or do functions at the end of this program run:\n";
print LOG "@{[values %INC]}","\n";
print LOG "_" x 80,"\n";
close LOG;
}