Perl如何验证路径是一个目录,而不能在同一个目录上调用opendir()?

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

我试图找到空的子目录并删除它们。我确信有更好的方法来实现这一点(我是一个差劲的程序员,对Perl比较陌生),但即便如此,我还是想了解我的方法有什么问题

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我明白了,谢谢你的澄清。