chown recursively

Discussion in 'Perl Misc' started by Tim O'Donovan, Jun 9, 2005.

  1. Quick newbie question! Could someone please point out how to use chown()
    on directories recursively.

    But mostly I'd like to know if there are actually any benefits over using:

    system("chown -R $uid:$gid $dir");


    Thanks very much!

    Tim
     
    Tim O'Donovan, Jun 9, 2005
    #1
    1. Advertising

  2. Tim O'Donovan

    Lars Eighner Guest

    In our last episode,
    <d8a7r8$6u$-infra.bt.com>,
    the lovely and talented Tim O'Donovan
    broadcast on comp.lang.perl.misc:

    > Quick newbie question! Could someone please point out how to use chown()
    > on directories recursively.


    > But mostly I'd like to know if there are actually any benefits over using:


    > system("chown -R $uid:$gid $dir");


    This is really a unix question, not a perl question. A word of
    warning, though: beware of -R and .* -- it will recurse upward
    because .. matches .* .

    --
    Lars Eighner http://www.larseighner.com/
    War on Terrorism: The Difference Between Us and Them
    "We should invade their countries, kill their leaders and
    convert them to Christianity." -- Ann Coulter
     
    Lars Eighner, Jun 9, 2005
    #2
    1. Advertising

  3. Well my question was actually concerning whether using a Perl function
    such as chown() had any benefits over using an equivalent system()
    function to achieve the same the results.

    Tim


    Lars Eighner wrote:
    > In our last episode,
    > <d8a7r8$6u$-infra.bt.com>,
    > the lovely and talented Tim O'Donovan
    > broadcast on comp.lang.perl.misc:
    >
    >
    >>Quick newbie question! Could someone please point out how to use chown()
    >>on directories recursively.

    >
    >
    >>But mostly I'd like to know if there are actually any benefits over using:

    >
    >
    >>system("chown -R $uid:$gid $dir");

    >
    >
    > This is really a unix question, not a perl question. A word of
    > warning, though: beware of -R and .* -- it will recurse upward
    > because .. matches .* .
    >
     
    Tim O'Donovan, Jun 9, 2005
    #3
  4. On 2005-06-09, Tim O'Donovan scribbled these
    curious markings:
    > Quick newbie question! Could someone please point out how to use chown()
    > on directories recursively.


    Perhaps a bit of File::Find?

    > But mostly I'd like to know if there are actually any benefits over using:
    >
    > system("chown -R $uid:$gid $dir");


    Who says chown exists on the target system? Who says it's in your path?
    It's generally a bad idea to "shell out" to external programs when you
    can do what you need to do with Perl.

    Best Regards,
    Christopher Nehren
    --
    I abhor a system designed for the "user", if that word is a coded
    pejorative meaning "stupid and unsophisticated". -- Ken Thompson
    If you ask the wrong people questions, you get "Joel on Software".
    Unix is user friendly. However, it isn't idiot friendly.
     
    Christopher Nehren, Jun 10, 2005
    #4
  5. On Fri, 10 Jun 2005 01:31:54 +0200, Christopher Nehren
    <> wrote:

    > On 2005-06-09, Tim O'Donovan scribbled these
    > curious markings:
    >> Quick newbie question! Could someone please point out how to use chown()
    >> on directories recursively.

    >
    > Perhaps a bit of File::Find?
    >
    >> But mostly I'd like to know if there are actually any benefits over
    >> using:
    >>
    >> system("chown -R $uid:$gid $dir");

    >
    > Who says chown exists on the target system? Who says it's in your path?
    > It's generally a bad idea to "shell out" to external programs when you
    > can do what you need to do with Perl.



    I agree that GENERALLY this is a bad idea. But since chmod in itself
    is very unix'ish, isn't it?, I think system should be permitted here.
    ....or if not permitted, I'd do a chmod to permit it...(uh)




    >
    > Best Regards,
    > Christopher Nehren




    --
    Kjetil Skotheim
     
    Kjetil Skotheim, Jun 10, 2005
    #5
  6. Christopher Nehren <> wrote:
    > On 2005-06-09, Tim O'Donovan scribbled these curious markings:


    [snip doing it in native Perl]


    >> But mostly I'd like to know if there are actually any benefits over using:
    >>
    >> system("chown -R $uid:$gid $dir");

    >
    > Who says chown exists on the target system?



    ie. portability between different machines.


    > Who says it's in your path?



    ie. portability between environments, even on *the same* machine.


    > It's generally a bad idea to "shell out" to external programs when you
    > can do what you need to do with Perl.



    I tell students:

    Doing it in native Perl will be safer, faster and more portable
    than "shelling out".

    Followed by some weasel wording about how that isn't an absolute,
    but that it applies in the vast majority of cases.

    Shelling out to Mathematica would very likely be preferrable to
    getting the same thing done in native Perl for instance. :)


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jun 10, 2005
    #6
  7. Thanks for all your informative replies, much appreciated. From now on
    I'll be replacing 'shell outs' with the appropriate Perl, where applicable.

    So I can assume that using:

    open(FIND, "find $path -lname '/home/$username/*' |");
    @links = <FIND>;
    close(FIND);

    to find all the symbolic links in the given path to files in a users
    home directory is also not the most resourceful method?!

    I have some rethinking to do... :)


    Thanks again,
    Tim
     
    Tim O'Donovan, Jun 10, 2005
    #7
  8. Tim O'Donovan <> wrote:

    > From now on
    > I'll be replacing 'shell outs' with the appropriate Perl, where applicable.


    > open(FIND, "find $path -lname '/home/$username/*' |");



    Pipe opens *are* "shelling out".


    > to find all the symbolic links in the given path to files in a users
    > home directory is also not the most resourceful method?!
    >
    > I have some rethinking to do... :)



    And some reading:

    perldoc File::Find

    perldoc -f -X


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jun 10, 2005
    #8
  9. Tim O'Donovan wrote:
    > Quick newbie question! Could someone please point out how to use
    > chown() on directories recursively.


    Sounds like a job for "use File::Find;".

    > But mostly I'd like to know if there are actually any benefits over
    > using:
    > system("chown -R $uid:$gid $dir");


    Of course, there are significant benefits. By using a Perl standard function
    you are avoiding to fork an external process and to call an external program
    that may or may not exist.
    In short you are writing portable code.

    jue
     
    Jürgen Exner, Jun 10, 2005
    #9
  10. Kjetil Skotheim wrote:
    > On Fri, 10 Jun 2005 01:31:54 +0200, Christopher Nehren
    >> Who says chown exists on the target system? Who says it's in your
    >> path? It's generally a bad idea to "shell out" to external programs
    >> when you can do what you need to do with Perl.

    >
    >
    > I agree that GENERALLY this is a bad idea. But since chmod in itself
    > is very unix'ish, isn't it?, I think system should be permitted here.
    > ...or if not permitted, I'd do a chmod to permit it...(uh)


    Where do you find chown on a Windows PC, on a Mac, or a any of the dozen and
    dozen OSs that are supported by Perl?

    jue
     
    Jürgen Exner, Jun 10, 2005
    #10
  11. Tim O'Donovan wrote:
    > open(FIND, "find $path -lname '/home/$username/*' |");
    > @links = <FIND>;
    > close(FIND);
    >
    > to find all the symbolic links in the given path to files in a users
    > home directory is also not the most resourceful method?!


    No, not exactly.
    See "perldoc -f -l" for a better way.

    jue
     
    Jürgen Exner, Jun 10, 2005
    #11
  12. On 2005-06-10, Tim Hammerquist scribbled these
    curious markings:
    > For example, if you decide to shell out to an external chown(1) command,
    > it will work on Linux, *BSD, Solaris, and even Mac OS X, and several
    > others...


    .... though it may fail if you use syntax supported in your programming
    environment's chown but not in your deployment environment's chown. For
    example, GNU chown accepts '.' as a separator for user and group, which
    is a violation of POSIX (though at least the documentation tells you
    this). FreeBSD's chown follows POSIX and explicitly disallows this. All
    the more reason to use Perl when possible.

    Best Regards,
    Christopher Nehren
    --
    I abhor a system designed for the "user", if that word is a coded
    pejorative meaning "stupid and unsophisticated". -- Ken Thompson
    If you ask the wrong people questions, you get "Joel on Software".
    Unix is user friendly. However, it isn't idiot friendly.
     
    Christopher Nehren, Jun 10, 2005
    #12
  13. > Well, if the directory is large, I bet shelling out the chown is *faster*
    > than doing it in Perl. The system call doesn't handle the -R functionality,
    > and I bet the C-implementation of traversing a directory tree in chown is
    > faster than most, if not every, Perl solution using File::Find.
    >
    > Of course, the strongest argument is: programmer time is more important
    > than CPU time. The time to program out
    >
    > system "chown -R $uid:$gid $dir";
    >
    > utterly dwarves the overhead of starting another process. (And note that
    > unless '$uid', '$gid' and '$dir' contain characters that are special to
    > shell, no shell will be started by perl - perl will call chown directly).



    Thanks for the alternative angle, excellent stuff. I'm considering using
    the original system() function now because of what you said about speed.
    This is part of a background script on a webserving machine that takes
    instructions from a file written to by a CGI script so the time each
    request takes to execute is of the utmost importance as we want to keep
    the user waiting for as little as possible for the result of the
    request. I've yet to find a way to use the sleep() function to sleep for
    less than a second (although I'm sure to find a module that will do
    this), so even though using the system() function might only reduce the
    time by a millisecond, this could cause the CGI script to sleep for a
    second more than it really needs to. Well, just under a second than it
    *needs* to but...


    > unless '$uid', '$gid' and '$dir' contain characters that are special to shell...


    This is also good to know as it will only ever be passed variables from
    the calling CGI script like so:

    system("chown -R 1100:80 /home/username/public_html");

    The $uid value is taken directly from a passwd file, $gid is a constant
    of 80 and if $username is not alphanumeric the CGI script will return an
    error.



    Tim
     
    Tim O'Donovan, Jun 11, 2005
    #13
  14. Abigail wrote:
    > Indeed. I'd write that as:
    >
    > @links = `find $path -lname '/home/$username/*'`;


    I have been getting rather confused trying to find a way to achieve this
    using the -l file test as a few people have suggested. From the perldoc
    it describes this as finding the symbolic links to a file that *don't*
    resolve; I need to find links that *do*. I will probably now use your
    suggestion to achieve this due to my frivolous attempts at using !-l !


    Tim
     
    Tim O'Donovan, Jun 11, 2005
    #14
  15. Abigail wrote:

    > Of course, the strongest argument is: programmer time is more important
    > than CPU time. The time to program out
    >
    > system "chown -R $uid:$gid $dir";
    >
    > utterly dwarves the overhead of starting another process. (And note that
    > unless '$uid', '$gid' and '$dir' contain characters that are special to
    > shell, no shell will be started by perl - perl will call chown directly).


    But even the briefest consideration of the question of whether or not
    $dir may contain shell meta character takes more programmer time than
    typing the extra punctuation to avoid this being an issue.

    system 'chown','-R',"$uid:$gid",$dir;
     
    Brian McCauley, Jun 11, 2005
    #15
  16. Tim O'Donovan

    Brian Wakem Guest

    Tim O'Donovan wrote:

    > I've yet to find a way to use the sleep() function to sleep for
    > less than a second
    >
    > Tim



    use Time::HiRes qw(sleep);

    sleep(0.2);



    --
    Brian Wakem
     
    Brian Wakem, Jun 11, 2005
    #16
  17. Tim O'Donovan

    Joe Smith Guest

    Tim Hammerquist wrote:
    > For example, if you decide to shell out to an external chown(1) command,
    > it will work on Linux, *BSD, Solaris, and even Mac OS X, and several
    > others... but fail on Win32.


    Works just fine in Win32 under cygwin.
    -Joe
     
    Joe Smith, Jun 12, 2005
    #17
  18. Tim O'Donovan

    Joe Smith Guest

    Tim O'Donovan wrote:

    > So I can assume that using:
    >
    > open(FIND, "find $path -lname '/home/$username/*' |");
    > @links = <FIND>;
    > close(FIND);
    >
    > to find all the symbolic links in the given path to files in a users
    > home directory is also not the most resourceful method?!


    You could capture the output from
    find2perl PATH -l -name '/home/USER/*'
    and modify that to do the -lname operation.
    Just change
    /^\/home\/jms\z/s &&
    print("$name\n");
    to
    readlink $_ =~ m%/home/USER/.*% &&
    push @links,$name;

    The find2perl program that comes with the perl installation doesn't
    do everything that GNU find does, but it is a good starting point.
    -Joe
     
    Joe Smith, Jun 12, 2005
    #18
  19. Tim O'Donovan <> wrote:
    Abigail <> wrote:
    > > Well, if the directory is large, I bet shelling out the chown is *faster*
    > > than doing it in Perl. The system call doesn't handle the -R functionality,
    > > and I bet the C-implementation of traversing a directory tree in chown is
    > > faster than most, if not every, Perl solution using File::Find.


    [ snip ]

    >
    > Thanks for the alternative angle, excellent stuff. I'm considering using
    > the original system() function now because of what you said about speed.


    Don't worry about the speed. I used the following setup on my
    workstation (3 GHz P4 running Ubuntu linux):

    directory with 10 sub-directories
    each with 10 sub-sub-directories (100 at this level)
    each with 10 sub-sub-sub-directories (1000 at this level)
    each with 10 files (10000 at this level)

    chown -R took about 0.05 seconds, calling Perl's builtin chown on each
    file/directory took 0.13 seconds, and building a large list of
    files/directories and feeding that to one call to Perl's chown took
    0.15 seconds.

    The thrown-together-in-a-few-minutes perl with path, uids, and gids
    hard coded is:

    #!/usr/bin/perl

    use warnings;
    use strict;
    use File::Find;

    my @list;

    sub wanted1 {
    chown(1000, 1588, $_);
    }

    sub wanted2 {
    push @list, $File::Find::name;
    }

    # dirs is the name of the directory to recursively chown
    if ( $ARGV[0] == 1 ) {
    find(\&wanted1, 'dirs');
    } elsif ( $ARGV[0] == 2 ) {
    find(\&wanted2, 'dirs');
    chown(1000, 1588, @list);
    }

    __END__


    Mike

    --
    Michael Zawrotny
    Institute of Molecular Biophysics
    Florida State University | email:
    Tallahassee, FL 32306-4380 | phone: (850) 644-0069
     
    Michael Zawrotny, Jun 13, 2005
    #19
    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. GfxGuy

    JNI/Linux/chown

    GfxGuy, May 28, 2005, in forum: Java
    Replies:
    6
    Views:
    2,524
    Ross Bamford
    May 29, 2005
  2. James Colannino

    os.chown()

    James Colannino, Nov 11, 2005, in forum: Python
    Replies:
    3
    Views:
    9,385
    Tim Roberts
    Nov 13, 2005
  3. Carsten Haese

    Re: chown'ing by script

    Carsten Haese, Jan 6, 2010, in forum: Python
    Replies:
    4
    Views:
    292
    Steve Holden
    Jan 6, 2010
  4. Brian Candler
    Replies:
    2
    Views:
    335
    Emiel van de Laar
    Mar 2, 2005
  5. superfly2

    chown and file ownership

    superfly2, Jul 21, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    134
    Jürgen Exner
    Jul 22, 2004
Loading...

Share This Page