我正在尝试编写一个脚本,从脚本所在的文件夹开始打印出文件结构.脚本工作正常,没有递归调用但是通过该调用它打印第一个文件夹的内容并崩溃并显示以下消息:closedir()尝试在printFiles.pl第24行无效的dirhandle DIR.文件夹被打印,执行到达最后一行,但为什么不进行递归调用?我应该如何解决这个问题呢?
#!/usr/bin/perl -w printDir("."); sub printDir{ opendir(DIR,$_[0]); local(@files); local(@dirs); (@files) = readdir(DIR); foreach $file (@files) { if (-f $file) { print $file . "\n"; } if (-d $file && $file ne "." && $file ne "..") { push(@dirs,$file); } } foreach $dir (@dirs) { print "\n"; print $dir . "\n"; printDir($dir); } closedir(DIR); }
解决方法
>你应该总是使用严格;并使用警告;在你的Perl程序开始时,特别是在你寻求帮助之前.这样Perl会出现很多直截了当的错误,否则你可能没有注意到.
>无效的文件句柄错误很可能是因为DIR是一个全局目录句柄,并且已经由先前执行的子例程关闭了.最好始终为文件和目录使用词法句柄,并测试返回代码以确保打开成功,如下所示
>无效的文件句柄错误很可能是因为DIR是一个全局目录句柄,并且已经由先前执行的子例程关闭了.最好始终为文件和目录使用词法句柄,并测试返回代码以确保打开成功,如下所示
opendir my $dh,$_[0] or die "Failed to open $_[0]: $!";
词法文件句柄的一个优点是当它们超出范围时它们会被隐式关闭,所以在子例程的末尾不需要你的closedir调用.
>本地并不意味着像这样使用.它不足以作为声明,并且您正在创建一切可以访问的全局变量的临时副本.最好用我的代替,就像这样
my @dirs; my @files = readdir $dh;
>此外,您在readdir中使用的文件名没有路径,因此您的文件测试将失败,除非您正在处理正在处理的目录,或者在测试之前将目录路径字符串附加到文件名.