Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   File::Glob - can it recurse? (http://www.velocityreviews.com/forums/t887544-file-glob-can-it-recurse.html)

Randall Perry 08-06-2004 03:39 PM

File::Glob - can it recurse?
 
I'm guessing not from reading the docs.

Here's what I can do with 2 lines using system:
system("chown -R $user.$http_group www/*");
($? eq 0) || die "Couldn't chown $user.$group www/*\n";

I'd like to use the perl chown() command so I tried this:
@filenames = glob "/admin/new_account_page/*";
chown $uid, $gid, @filenames || die;

But it doesn't recurse through subdirectories. Is there a better way
to accomplish this than by using system()?

Randy

Paul Lalli 08-06-2004 03:52 PM

Re: File::Glob - can it recurse?
 
On Fri, 6 Aug 2004, Randall Perry wrote:

> I'm guessing not from reading the docs.
>
> Here's what I can do with 2 lines using system:
> system("chown -R $user.$http_group www/*");
> ($? eq 0) || die "Couldn't chown $user.$group www/*\n";
>
> I'd like to use the perl chown() command so I tried this:
> @filenames = glob "/admin/new_account_page/*";
> chown $uid, $gid, @filenames || die;
>
> But it doesn't recurse through subdirectories. Is there a better way
> to accomplish this than by using system()?



I feel like I'm taking on the job of advocating this module lately.

The standard File::Find module is helpful for recursing through
directories. The non-standard File::Find::Rule and File::Finder provide
alternate syntaxes as well.

(untested)

#!/usr/bin/perl
use strict;
use warnings;
use File::Find

my ($uid, $gid) = @ARGV; #assuming UID and GID are passed in command line.
my @files;

sub wanted{
push @files, $File::Find::name if -f $File::Find::name;
}

find (\&wanted, '/admin/new_account_page/');
chown $uid, $gid, @files or die "Cannot chown: $!";

__END__

Brian McCauley 08-06-2004 04:30 PM

Re: File::Glob - can it recurse?
 

Randall Perry wrote:

[ of glob() ]

> But it doesn't recurse through subdirectories. Is there a better way
> to accomplish this than by using system()?


File::Find


Ben Morrow 08-06-2004 05:30 PM

Re: File::Glob - can it recurse?
 

Quoth rgp@systame.com (Randall Perry):
> I'm guessing not from reading the docs.
>
> Here's what I can do with 2 lines using system:
> system("chown -R $user.$http_group www/*");
> ($? eq 0) || die "Couldn't chown $user.$group www/*\n";
>
> I'd like to use the perl chown() command so I tried this:
> @filenames = glob "/admin/new_account_page/*";
> chown $uid, $gid, @filenames || die;
>
> But it doesn't recurse through subdirectories. Is there a better way
> to accomplish this than by using system()?


File::Find, as usual...

Ben

--
Although few may originate a policy, we are all able to judge it.
- Pericles of Athens, c.430 B.C.
ben@morrow.me.uk

Randall Perry 08-07-2004 03:09 PM

Re: File::Glob - can it recurse?
 
> > But it doesn't recurse through subdirectories. Is there a better way
> > to accomplish this than by using system()?

>

Thanks for the input, but for me, the answer here is no. :-)
Calling system() is much simpler.

Adding recursive capabilities to chown(), chmod() would be ideal.

>
> I feel like I'm taking on the job of advocating this module lately.
>
> The standard File::Find module is helpful for recursing through
> directories. The non-standard File::Find::Rule and File::Finder provide
> alternate syntaxes as well.
>
> (untested)
>
> #!/usr/bin/perl
> use strict;
> use warnings;
> use File::Find
>
> my ($uid, $gid) = @ARGV; #assuming UID and GID are passed in command line.
> my @files;
>
> sub wanted{
> push @files, $File::Find::name if -f $File::Find::name;
> }
>
> find (\&wanted, '/admin/new_account_page/');
> chown $uid, $gid, @files or die "Cannot chown: $!";
>
> __END__


Uri Guttman 08-07-2004 04:20 PM

Re: File::Glob - can it recurse?
 
>>>>> "RP" == Randall Perry <rgp@systame.com> writes:

>> > But it doesn't recurse through subdirectories. Is there a better way
>> > to accomplish this than by using system()?

>>

RP> Thanks for the input, but for me, the answer here is no. :-)
RP> Calling system() is much simpler.

RP> Adding recursive capabilities to chown(), chmod() would be ideal.

no that wouldn't be ideal. perl tries to keep its system calls as
similar as possible to the real kernel calls. chmod the system call
doesn't recurse but chmod the utility can. they are different things
even if they have the same name and have overlapping functionality. it
isn't hard to use file::find and then call chmod on the results (in the
callback or on the collected results.

the best thing to do would be to write a module that does this and put
it on cpan. then it will be easy to use and everyone can enjoy the
fruits of your labor. there is a file::chmod module which handles
different modes for setting the chmod bits but it doesn't recurse. maybe
you can work with its author to add recursion to it. forking out to a
process just to recurse is not my idea of a good thing.

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

J. Romano 08-08-2004 02:33 PM

Re: File::Glob - can it recurse?
 
rgp@systame.com (Randall Perry) wrote in message news:<fac8f6c0.0408060739.537c19bf@posting.google. com>...
>
> I'd like to use the perl chown() command so I tried this:
>
> @filenames = glob "/admin/new_account_page/*";
> chown $uid, $gid, @filenames || die;
>
> But it doesn't recurse through subdirectories. Is there a better way
> to accomplish this than by using system()?


There is a simple work-around to your problem, but it's not really
all that elegant.

One of the nice things about the glob() function is that it can
take wildcards in the directory names, as well as in the file names.
So you can replace your line:

@filenames = glob "/admin/new_account_page/*";

with:

@filenames = glob "/admin/new_account_page/*";
push @filenames, glob "/admin/new_account_page/*/*";
push @filenames, glob "/admin/new_account_page/*/*/*";

push @filenames, glob "/admin/new_account_page/*/*/*/*";
push @filenames, glob "/admin/new_account_page/*/*/*/*/*";
push @filenames, glob "/admin/new_account_page/*/*/*/*/*/*";

and now you have recursion that's five levels deep.

Like I said, this isn't really all that elegant of a solution,
since your directory structure may have more (or less) than five
levels of recursion. If it had twenty levels of nested directories,
you'd have to have 21 total glob() lines to get all your files! If it
had only two levels of recursion, then three of those lines would be
useless.

There is a work-around for this problem, too. You can always put
the glob string in a loop that stops when it finds no more files, like
this:

$globString = "/admin/new_account_page/*";
while ( @globbedFiles = glob($globString) ) # note the single "="
{
push @filenames, @globbedFiles;
$globString .= "/*"; # for the next time through the loop
}
print "Found files: @filenames\n";

This approach should work, but I have to say that the standard
approach is to use the File::Find module, as it was meant to be used
for tasks just like yours. If you find the documentation for
File::Find to be a bit confusing, you can use the "find2perl"
executable (which you probably already have) to create most of the
code for you, with this command:

find2perl /admin/new_account_page -name "*"

Then all you'd have to do is put this line of yours in the wanted()
subroutine:

chown $uid, $gid, @filenames or die;

and then run that script.

I hope this helps, Randy.

-- Jean-Luc

Randall Perry 08-11-2004 01:18 PM

Re: File::Glob - can it recurse?
 
Uri Guttman <uri@stemsystems.com> wrote in message news:<x7hdre6ht9.fsf@mail.sysarch.com>...

> chmod the system call
> doesn't recurse but chmod the utility can. they are different things
> even if they have the same name and have overlapping functionality.


Didn't know that.

Thanks everyone for the info.

Randall Perry 08-11-2004 01:22 PM

Re: File::Glob - can it recurse?
 
Uri Guttman <uri@stemsystems.com> wrote in message news:<x7hdre6ht9.fsf@mail.sysarch.com>...

> chmod the system call
> doesn't recurse but chmod the utility can. they are different things
> even if they have the same name and have overlapping functionality.


Didn't know that.

Thanks everyone for the info.

Randall Perry 08-11-2004 01:23 PM

Re: File::Glob - can it recurse?
 
Uri Guttman <uri@stemsystems.com> wrote in message news:<x7hdre6ht9.fsf@mail.sysarch.com>...

> chmod the system call
> doesn't recurse but chmod the utility can. they are different things
> even if they have the same name and have overlapping functionality.


Didn't know that.

Thanks everyone for the info.


All times are GMT. The time now is 12:55 PM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.