DrWhy has asked for the wisdom of the Perl Monks concerning the following question:

Is there an easier/more reliable/more complete way to copy a file in perl and preserve file permissions, ownership, etc. than:

use File::Copy; my $file = '/whatever/you/want'; my $bak = $file . '.bak'; (undef, undef, $mode, undef, $uid, $gid) = stat $file; copy($file, $bak); chmod $mode, $bak; chown $uid, $gid, $bak;

Note this code has not been tested; I'm just presenting the basic idea i have in mind and am hoping not to have to implent :)

...hoping I just missed the right module in my search through CPAN...

--DrWhy

Replies are listed 'Best First'.
Re: Perl cp -p?
by Limbic~Region (Chancellor) on Aug 20, 2004 at 22:02 UTC
    DrWhy,
    Have you taken a look at File::NCopy? The set_permission and preserve thingies look interesting though I have to admit I didn't try it out.

    Cheers - L~R

      I tried it and it seems to work on my Solaris box/Perl 5.6.1: Here's some test code if anyone is interested:

      use File::NCopy; $c = new File::NCopy(preserve => 1); $c->copy("test", "test2");

      This code successfully preserved permissions, group, and modified/access times. Presumably owner would also be preserved, but I'm not running as root so didn't bother to test that. Without preserve => 1, permissions are still preserved but the other stuff isn't.

      Thanks, L~R.

      -- DrWhy

Re: Perl cp -p?
by TomDLux (Vicar) on Aug 21, 2004 at 01:50 UTC

    Minor detour ... I am especially unfond of:

    (undef, undef, $mode, undef, $uid, $gid) = stat $file;

    You wind up with all this glop concealing what components you're actually interested in. I prefer taking the return values as a list, and slice-ing out the portions you want:

    ($mode, $uid, $gid) = ( stat $file )[2,4,5];

    Yes, you have some glop on the right hand side, but it's a standard, recognized mechanism which extends your power once you get used t it.

    The left hand side is clear, listing and naming the values you are interested in. The right hand side adds some parentheses, which focus attention on the operation which is providing the values, followed by the slicing brackets which can almost be ignored. They are the mechanism for selecting the data, but beyond that are uninteresting.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

      Or you could use File::stat:

      use File::stat; $st = stat($file) or die "No $file: $!"; my $mode = $st->mode; my $uid = $st->uid; my $gid = $st->gid;

      A few more lines (or not, if you just use $st->field directly), but the extra typing makes up in clarity and not having to do a perldoc -f stat to figure out where each attribute is in the results.

      -b