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

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 に答える