我打算以递归方式遍历包含这段perl脚本的目录。 我们的想法是遍历其父目录包含perl脚本的所有目录,并将所有文件路径列为单个数组变量。然后返回列表。
出现错误消息:
readdir() attempted on invalid dirhandle $DIR at xxx
closedir() attempted on invalid dirhandle $DIR at xxx
附上代码供参考,提前谢谢。
use strict;
use warnings;
use Cwd;
our @childfile = ();
sub recursive_dir{
my $current_dir = $_[0]; # a parameter
opendir(my $DIR,$current_dir) or die "Fail to open current directory,error: $!";
while(my $contents = readdir($DIR)){
next if ($contents =~ m/^\./); # filter out "." and ".."
#if-else clause separate dirs from files
if(-d "$contents"){
#print getcwd;
#print $contents;
#closedir($DIR);
recursive_dir(getcwd."/$contents");
print getcwd."/$contents";
}
else{
if($contents =~ /(?<!\.pl)$/){
push(@childfile,$contents);
}
}
}
closedir($DIR);
#print @childfile;
return @childfile;
}
recursive_dir(getcwd);
答案 0 :(得分:0)
请告诉我们这是否是作业?欢迎您向作业寻求帮助,但它会改变您应给予的答案。
您依靠getcwd
为您提供当前正在处理的目录,但您永远不会更改当前工作目录,因此您的程序将无限循环并最终耗尽内存。您只需使用$current_dir
代替。
我不相信您显示的程序可以生成这些错误消息。您的代码会检查opendir
是否已成功并且程序将死亡,除非$DIR
有效,因此后续readdir
和closedir
必须使用有效处理
其他一些观点:
像# a parameter
这样的评论很荒谬,只会让您的代码变得混乱
大写字母通常保留用于包名称等全局标识符。并且$dir
是目录句柄的可怜名称,因为它也可能表示目录名称或目录路径。使用$dir_handle
或$dh
使用负面后卫来检查文件名是否以.pl
结尾是很疯狂的。只需使用push @childfile, $contents unless $contents =~ /\.pl$/
您永远不会使用子程序中的返回值,因此从每次调用返回可能是巨大数组的内存都是浪费。 @childfile
可在整个计划中访问,因此您可以直接从任何地方访问
不要将标量变量放在双引号内。它只是将值强制为字符串,这可能是不必要的,并可能导致奥术错误。仅使用-d $contents
您可能希望忽略符号链接,否则您可能无休止地循环。您应该将else { ... }
更改为elsif (-f $contents) { ... }