1

我有一个 perl 脚本,它读取一个目录并打印出该目录的文件等等,但是我无法这样做,因为我没有读取权限..

sub func {
    my $some_dir = $_[0];
    opendir(my $DIR, $some_dir) or die "ERROR!";
    while (my $file = readdir($DIR)) {
        if (-r $file) {              # Read permissions
            print "hurray $file!\n";
            if (-d $file) {          # Directory 
               print "entering dir...\n";
               func($file);
            }
        } else {                     # No read permissions..
            print "no permissions for $file\n";
        }
    }
    return;
}

如果我使用文件夹结构运行此代码:

file
folder
-file
-file
-folder
--file
--file

我得到:

hurray file!
hurray folder!
entering dir..
no permissions for file
no permissions for file
no permissions for file # no idea why?? should be folder
no permissions for file
no permissions for file

所以它只打印起始目录中的文件/文件夹,其他所有内容都没有读取权限。然后我尝试chmod 777 file对子目录中的所有文件执行操作,但我得到了相同的结果..

有任何想法吗?

谢谢。

编辑 - 添加了一些东西来消除混乱。

4

2 回答 2

3

以下是readdir(由 获得perldoc -f readdir)的文档:

返回由“opendir”打开的目录的下一个目录条目。如果在列表上下文中使用,则返回目录中的所有其余条目。如果没有更多条目,则在标量上下文中返回未定义值或在列表上下文中返回空列表。

如果您打算从“readdir”中对返回值进行文件测试,则最好在有问题的目录之前添加。否则,因为我们没有在那里“chdir”,它会测试错误的文件。

opendir(my $dh, $some_dir) || die "can't opendir $some_dir: $!";
@dots = grep { /^\./ && -f "$some_dir/$_" } readdir($dh);
closedir $dh;

因此:

  1. if (-r $file)不会工作,你将不得不说if (-r "$some_dir/$file")

  2. readdir还将返回目录“。” 和 '..' 你可能对这些不感兴趣。

于 2013-05-27T12:03:27.737 回答
1

问题是您的工作目录没有改变。例如,假设您的起始目录是/home

opendir(my $DIR, $some_dir) or die "ERROR!";    # working dir is /home
while (my $file = readdir($DIR)) {
    if (-r $file) {                             # checks for /home/$file
        print "hurray $file!\n";                # but path is /home/folder/$file
        if (-d $file) {
           print "entering dir...\n";           
           func($file);                         # enters /home/folder/$file

所以从/home,脚本看不到文件folder/file,或者,至少不是你的意思。我发现我的测试目录和脚本工作目录中有一些类似命名的文件,这些文件给出了误报。

解决方案是chdir酌情或在检查权限时将路径添加到文件名。您还应该补偿.(当前目录)和..(父目录)。当我按原样运行您的脚本时,它变成了无限循环。

但当然,最好的解决方案是使用适当的模块来完成这项工作File::Find

use strict;
use warnings;
use File::Find;

my $file = shift;   # your file name
find(sub { if (-r) { print "Hurray $File::Find::name\n"; } }, $file);

这将递归地遍历文件夹并打印出与-r权限匹配的文件名。如果您阅读文档,File::Find您会发现find子程序会自动更改目录,并使用变量:

$_                    # file name e.g. 'file.txt'
$File::Find::name     # full relative path e.g. 'folder/file.txt'
$File::Find::dir      # current folder name e.g. 'folder'
于 2013-05-27T12:16:08.307 回答