Perl如何验证路径是一个目录,而不能在同一个目录上调用opendir()?
我试图找到空的子目录并删除它们。我确信有更好的方法来实现这一点(我是一个差劲的程序员,对Perl比较陌生),但即便如此,我还是想了解我的方法有什么问题Perl如何验证路径是一个目录,而不能在同一个目录上调用opendir()?,perl,find,Perl,Find,我试图找到空的子目录并删除它们。我确信有更好的方法来实现这一点(我是一个差劲的程序员,对Perl比较陌生),但即便如此,我还是想了解我的方法有什么问题 use strict; use warnings; use File::Basename; use File::Find my $lambda2 = sub { my $path = $File::Find::name; if ( -d $path ) { print("Directory: ", $p
use strict;
use warnings;
use File::Basename;
use File::Find
my $lambda2 = sub
{
my $path = $File::Find::name;
if ( -d $path )
{
print("Directory: ", $path, "\n");
# Define anonymous function to test if directory is empty
my $hasContent = sub
{
my $directory = shift;
opendir ( my $dh, $directory );
return scalar ( grep { $_ ne "." && $_ ne ".." } readdir ( $dh ) );
};
# Remove item if it is an empty directory
if ( ! $hasContent->( $path ) )
{
rmdir( $path );
}
}
};
my $directory = "/Users/username/testdir/";
find( { wanted => $lambda2, no_chdir => 1 }, $directory );
如果testdir有一个名为testsubdir的空子目录,比如说,我会得到看似矛盾的响应:
Directory: /Users/username/testdir
Directory: /Users/username/testdir/testsubdir
Can't opendir(/Users/username/testdir/testsubdir): No such file or directory
打印后一个目录意味着它通过了-d检查,但随后的错误消息表示没有这样的目录。据我所知,两者之间没有发生任何事情 可以说,代码正在删除
查找下的目录
最简单的修复方法:将find
更改为finddepth
,例如,自
在为目录的内容调用函数后,它将为目录调用&want
函数
(原来的重点) 然后,它不会尝试调用刚刚删除的目录上的所需的
或者,只需收集find
中的空目录列表,并在find
完成后删除它们。让我们加入一些日志语句,看看发生了什么:
my $lambda2 = sub {
my $path = $File::Find::name;
if ( -d $path ) {
print("Directory: ", $path, "\n");
my $hasContent = sub {
my $directory = shift;
opendir ( my $dh, $directory );
return scalar ( grep { $_ ne "." && $_ ne ".." } readdir ( $dh ) );
};
my $hc = $hasContent->($path);
print STDERR "hc($path) = $hc\n";
if (! $hc) {
print STDERR "Deleting $path\n";
rmdir( $path );
}
}
};
$ mkdir -p /Users/username/testdir/testsubdir
$ perl subdir.pl
Directory: /Users/username/testdir
hc(/Users/username/testdir) = 1
Directory: /Users/username/testdir/testsubdir
hc(/Users/username/testdir/testsubdir) = 0
Deleting /Users/username/testdir/testsubdir
Can't opendir(/Users/username/testdir/testsubdir): No such file or directory
at subdir.pl line 26.
因此,代码或多或少是按设计工作的,只是File::Find
试图在删除它之后遍历/Users/username/testdir/testsubdir
。使用du
和awk
列出$target\u目录下的所有空目录
du $target_directory| awk '$1=="0"{print $2}'
du $target_directory| awk '$1=="0"{system("rmdir "$2);}'
删除$target\u目录下的所有空目录
du $target_directory| awk '$1=="0"{print $2}'
du $target_directory| awk '$1=="0"{system("rmdir "$2);}'
你检查权限了吗?当opendir失败时,您的代码不会打印出错误消息,因此拥有生成确切错误消息的代码可能会有所帮助。您是否愿意接受其他非perl解决方案?使用find和du.See,我看不出在删除opendir之后,它是如何在testsubdir上第二次被调用的。或者你是说opendir错误消息不是来自File::Find内部的代码?@JamesMachin它确实来自“内部”(调用了want
),因为它试图遍历项目列表(而一个子目录刚刚被处理和删除)。@zdim我明白了,谢谢你的澄清。