File::Glob - can it recurse?

Discussion in 'Perl Misc' started by Randall Perry, Aug 6, 2004.

  1. 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
     
    Randall Perry, Aug 6, 2004
    #1
    1. Advertising

  2. Randall Perry

    Paul Lalli Guest

    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__
     
    Paul Lalli, Aug 6, 2004
    #2
    1. Advertising

  3. 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
     
    Brian McCauley, Aug 6, 2004
    #3
  4. Randall Perry

    Ben Morrow Guest

    Quoth (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, Aug 6, 2004
    #4
  5. > > 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__
     
    Randall Perry, Aug 7, 2004
    #5
  6. Randall Perry

    Uri Guttman Guest

    >>>>> "RP" == Randall Perry <> 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 ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Aug 7, 2004
    #6
  7. Randall Perry

    J. Romano Guest

    (Randall Perry) wrote in message news:<>...
    >
    > 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
     
    J. Romano, Aug 8, 2004
    #7
  8. Uri Guttman <> wrote in message news:<>...

    > 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, Aug 11, 2004
    #8
  9. Uri Guttman <> wrote in message news:<>...

    > 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, Aug 11, 2004
    #9
  10. Uri Guttman <> wrote in message news:<>...

    > 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, Aug 11, 2004
    #10
  11. Uri Guttman <> wrote in message news:<>...

    > 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, Aug 11, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Georgy Pruss
    Replies:
    15
    Views:
    734
    Tim Roberts
    Dec 1, 2003
  2. Tim Peters
    Replies:
    1
    Views:
    367
    Duncan Booth
    Dec 1, 2003
  3. Sean Berry

    Question about glob.glob <--newbie

    Sean Berry, May 4, 2004, in forum: Python
    Replies:
    3
    Views:
    350
    David M. Cooke
    May 4, 2004
  4. Replies:
    0
    Views:
    331
  5. qanda
    Replies:
    1
    Views:
    123
    Tassilo v. Parseval
    Sep 15, 2003
Loading...

Share This Page