Re: Copying a directory recursively
by arden (Curate) on Mar 10, 2004 at 01:25 UTC
|
Have you looked at File::DirSync yet? It hasn't been updated in about eight months, but it looks like it should do the trick.
- - arden. | [reply] |
|
|
| [reply] |
Re: Copying a directory recursively
by broquaint (Abbot) on Mar 10, 2004 at 02:34 UTC
|
With a bit of help from the File:: modules I've come up with this code snippet
use strict;
use warnings;
use File::Basename 'basename';
use File::Find::Rule 'find';
use File::Path 'mkpath';
use File::Copy 'copy';
use File::Spec::Functions qw/ splitdir catdir splitpath catfile /;
$::PROG = basename $0;
my($orig, $new) = @ARGV;
die "Usage: $::PROG SRC DEST\n"
unless defined $new and defined $orig;
my $iter = find start => $orig;
while(my $ent = $iter->match) {
if(-d $ent) {
my $mode = ( stat $ent )[2];
my @src = splitdir $ent;
my $dest = catdir $new => @src;
mkpath $dest => 0, $mode
or die "$::PROG: Couldn't create '$ent': $!";
} else {
my @src = splitpath $ent;
my $dest = catfile $new => @src;
copy $ent => $dest
or die "$::PROG: Couldn't copy '$ent': $!";
}
}
Not having a plethora of systems to work with, I couldn't say how portable that is, but given the ubiquity of File::Spec it should be relatively reliable. However, I'd say in this case it'd probably be simpler just to have a switch-esque statement to call the appropriate system copying tool per system to get reliable and consistent recursive copying.
| [reply] [d/l] |
|
|
Be wary of the File::Find module, it has a memory leak. See File::Find memory leak I tend to avoid it now.
Is there a Win32 module similar to File::Dirsync or File::Repl mentioned above? My search on ppm3 didn't find anything. I'm looking for a similar solution myself. It my searches prove unsuccessful I'll end up writing my own, just researching now.
Thanks
Dean
| [reply] |
|
|
File::Repl works on Win32. ppm probably doesn't have it, but IIRC you can install from CPAN without needing a compiler.
perl -MCPAN -e "install File::Repl".
I would try that -- if you have problems, you may need to download a free copy of nmake from Microsoft (and possibly rename it make) to get CPAN to work, but other than that, it should be fine. Again, I don't think a compiler is required. We use this module at Work on Win32 quite often in our build system. No problems yet!
| [reply] |
|
|
|
|
Re: Copying a directory recursively
by Abigail-II (Bishop) on Mar 10, 2004 at 02:29 UTC
|
How portable do you want it to be? Portable between any
POSIX system? How should it behave when encountering non-files, like fifos or symbolic links? How do you want
permissions and ownership be handled?
I'd go for a non-Perl solution, and choice any off:
- cp -R or cp -a
- tar cf - src | (cd dest; tar xf -)
- cpio
- rsync
I've copied directories zillions of times, but never with
a pure Perl solution.
Abigail | [reply] |
Re: Copying a directory recursively
by bl0rf (Pilgrim) on Mar 10, 2004 at 02:05 UTC
|
I raced off to program a solution in Perl, trying to beat everyone else. The result follows, although it doesn't handle binary and Only now I've noticed that you wanted recursion, but that is fairly easy to add on.
#!usr/bin/perl -W
# pure Perl directory copying script
use File::Find;
$from = $ARGV[0]; # from should be full path
$to = $ARGV[1]; # to should have / at the end
mkdir( $to ) || die "cant mkdir $to: $!";
find( \©routine, $from );
sub copyroutine
{
if( $_ eq '.' || $_ eq '..' ){ return 1 }
print "got $_\n";
open( FROM, $_ ) || die "cant open $_: $!";
open( TO, "> $to$_" ) || die "cant make $to$_ : $!";
while( $line = <FROM> )
{
print TO $line;
}
close TO;
close FROM;
}
I know just how much everyone likes to perfect solutions, and add alternate ones - so I leave it to others to implement recursion and binary handling. The above code works with a flat directory on my trusty 333Mhz windows box.
The guy with the awful signature
| [reply] [d/l] |
Re: Copying a directory recursively
by TomDLux (Vicar) on Mar 10, 2004 at 01:50 UTC
|
Who needs a Perl solution when rsync works on all significant platforms? ... even between platforms!
--
TTTATCGGTCGTTATATAGATGTTTGCA
| [reply] |
|
|
Last I heard, there's not a working rsync for VMS...yet.
| [reply] |
|
|
| [reply] |
|
|
Re: Copying a directory recursively
by thunders (Priest) on Mar 10, 2004 at 03:30 UTC
|
Have you tried File::NCopy it appears to do what you need. I've used it in the past on Win32 with some success. Also the core modules File::Find and File::Copy together should do most of what you need. | [reply] |
Re: Copying a directory recursively
by Happy-the-monk (Canon) on Mar 10, 2004 at 01:34 UTC
|
Just a non-perlish train of thought...
<!perl>
tar cf - source | ( cd target ; tar xf - )
</!perl>
that's my unox recursive copying incantation.
But how would it translate to Perl?
it seems Archive::Tar only deals with file archives at first sight.
But it might be twisted to work as the tar loop, or not? And what about PAR?
| [reply] |
Re: Copying a directory recursively
by zentara (Cardinal) on Mar 10, 2004 at 16:49 UTC
|
This is the easiest I've come across:
#!/usr/bin/perl
use File::NCopy;
$file = File::NCopy->new(recursive => 1);
$file->copy($dir1, $dir2); # Copy $dir1 to $dir2 recursively
I'm not really a human, but I play one on earth.
flash japh
| [reply] [d/l] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: Copying a directory recursively
by Plankton (Vicar) on Mar 10, 2004 at 05:08 UTC
|
I am assuming that when you say "pure perl" you mean without having to use a Perl module. In that case why not case off of the $^O (OS) variable ... you know ... something like this ...
sub setRecursiveCopyCommand {
my $OS = $^O;
if ( $OS eq 'VMS' ) {
return whatever the hell they do in VMS
} elsif ( $OS eq 'PLAN9' ) {
return whatever the hell they do in PLAN9
} elsif ( $OS eq monkeys_fly_out_of_my_ass ) {
you get the picture
} else {
...
}
Note above code is untested. And may require some effort on your part ... :P
| Plankton: 1% Evil, 99% Hot Gas. |
| [reply] [d/l] |
|
|
Because trying to shell out to xcopy wasn't working =/. Actually by "pure perl" I meant not utilizing any other binary.
| [reply] |
|
|
| [reply] |
|
|
Re: Copying a directory recursively
by Anonymous Monk on Mar 10, 2004 at 04:52 UTC
|
Sorry this is not a Perl solution but this solution should be portable to all *nix OS's and Windows OS that cygwin installed on them ...
$ cp -r src/* tgt
| [reply] [d/l] |