Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > File::Glob - can it recurse?

Reply
Thread Tools

File::Glob - can it recurse?

 
 
Randall Perry
Guest
Posts: n/a
 
      08-06-2004
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
 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      08-06-2004
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__
 
Reply With Quote
 
 
 
 
Brian McCauley
Guest
Posts: n/a
 
      08-06-2004

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

 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      08-06-2004

Quoth http://www.velocityreviews.com/forums/(E-Mail Removed) (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.
(E-Mail Removed)
 
Reply With Quote
 
Randall Perry
Guest
Posts: n/a
 
      08-07-2004
> > 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__

 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      08-07-2004
>>>>> "RP" == Randall Perry <(E-Mail Removed)> 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 ------ (E-Mail Removed) -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
J. Romano
Guest
Posts: n/a
 
      08-08-2004
(E-Mail Removed) (Randall Perry) wrote in message news:<(E-Mail Removed). 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
 
Reply With Quote
 
Randall Perry
Guest
Posts: n/a
 
      08-11-2004
Uri Guttman <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...

> 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.
 
Reply With Quote
 
Randall Perry
Guest
Posts: n/a
 
      08-11-2004
Uri Guttman <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...

> 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.
 
Reply With Quote
 
Randall Perry
Guest
Posts: n/a
 
      08-11-2004
Uri Guttman <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...

> 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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can Groovy be used in an applet and/or can it generate the Java bytecodes that then can be used in an applet? Casey Hawthorne Java 1 03-18-2009 12:56 AM
Word Docs Won't Open, Can't Be E-Mailed, Can't Be Deleted, Can't Be Copied, Etc. Martin Computer Support 16 02-24-2009 07:35 PM
Wireless can get internet but can't see network -- can when wired 02befree Computer Support 0 12-24-2007 09:10 PM
SOLVED - can't open file in windows media player / WMP. But can in VLC - video LAN .. Now can in WMP jameshanley39@yahoo.co.uk Computer Information 2 09-19-2007 02:53 AM
Windows can see mapped drives, but applications can't? =?Utf-8?B?RGFuaWVsIEVpY2hvcm4=?= Wireless Networking 3 11-18-2004 11:03 PM



Advertisments