【问题标题】:No read permissions even though I have set them in xubuntu?即使我在 xubuntu 中设置了它们也没有读取权限?
【发布时间】:2013-05-27 11:31:27
【问题描述】:

我有一个 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,但我得到了相同的结果..

有什么想法吗?

谢谢。

编辑 - 添加了一些内容以消除混乱。

【问题讨论】:

  • 您的文件夹是否设置了execute 位?
  • 我相信是这样,对我要读取其内容的文件夹执行ls -l 会显示drwxrwxrwx
  • 也许您应该尝试在失败消息中也打印文件名,例如"no permissions for '$file'\n".
  • 是的,对不起,我只是在我的示例中省略了这一点。如果我将$file 添加到打印中,它会按预期为每个文件显示no permissions for file(正确的文件名)。

标签: perl recursion directory readdir


【解决方案1】:

这是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 也将返回目录 '.'和 '..' 你可能对这些不感兴趣。

【讨论】:

  • 嗨,刚刚用-r $some_dir/$file-r $some_dir\/$file 尝试过,结果相同.. 编辑!没关系,它需要更多的修补。谢谢!
  • 这是因为当您仔细阅读脚本的输出时,您的第二个问题应该会变得很明显:“entering dir..”
【解决方案2】:

问题是您的工作目录没有改变。例如,假设你的起始目录是/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'

【讨论】:

  • readdir 是一个既好又坏的精确工具。大多数时候,我认为使用glob 更容易、更合适。当然还有 File::Find for recursion。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 2015-09-02
  • 1970-01-01
  • 2018-03-08
  • 2019-02-01
相关资源
最近更新 更多