Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Dir recursion

by AcidHawk (Vicar)
on May 07, 2004 at 07:19 UTC ( #351377=perlquestion: print w/replies, xml ) Need Help??

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


I am fighting with dir recursion. I have the following dir structure on machine A and want to ftp it to machine B. I only want the files that are NOT on machine B to be put there (I.e. if they do not exist).

test _ |_subdir1 | |_lowersub1 | |_lowertest1.txt | |_subdir2 | |_lowersub2 | | |_anotherlower2 | | | |_anotherlowertest2.txt | | |_lowersubtest2.txt | |_subtest2.txt | |_subdir3 |_test1.txt
I am able to handle the dirs but I keep missing the files in subdir2 (I.e. the directories get created but not the files.) If I run this again (I.e. the dirs are already there the files get put in their respective folders.)

This is what I have ...

#! /usr/bin/perl use strict; use warnings; use Net::FTP; my $test_exists = 0; my $ftp = Net::FTP->new("machineB", Debug => 0) or die "Cannot connect + to machineB: $@"; $ftp->login('usr','pass') or die "Cannot login ", $ftp->message; my $result = $ftp->ls("/myincomming") or die "ls failed ", $ftp->messa +ge; foreach (@{$result}) { print "$_\n"; if ($_ =~ /(.)myincomming(.)test/i) { print "Dir Exists\n"; $test_exists = 1; last; } } unless ($test_exists) { $ftp->mkdir("\\myincomming\\test") or die "mkd +ir failed ", $ftp->message; } my $firstdir = "./Test"; &ProcessStruct("$firstdir"); sub ProcessStruct { my $dir = shift; my $ftp_dir_exists = 0; my $file; print "DIR = $dir\n"; opendir DIR, $dir || die "cannot check dir $dir : $!\n"; my @files = readdir DIR; closedir DIR; foreach my $file(@files) { next if $file =~/^\./; if (-f "$dir/$file") { print "SEND $dir/$file to ftp server\n"; &Put_File($dir, $file); } else { $file = "$dir/$file"; my @ret = $ftp->ls("/Cubes/$file/.."); foreach (@ret) { my @subdirs = split /\\/, $_; if ($file =~ /$subdirs[$#subdirs]/i) { $ftp_dir_exists = 1; last; } } unless ($ftp_dir_exists) { $ftp->mkdir("/myincomming/$file +") or die " next mkdir failed ", $ftp->message; } $ftp_dir_exists = 0; &ProcessStruct("$file"); } } close DIR; } sub Put_File { my $dir = shift; my $file = shift; my @ret = $ftp->ls("/myincomming/$dir"); foreach (@ret) { if ($_ =~ /$file/i) { print "DONT PUT FILES = $_\n"; } else { $ftp->put("$dir/$file", "/myincomming/$dir/$file") or die +"Cannot put file ", $ftp->message; } } }
Of all the things I've lost in my life, its my mind I miss the most.

Replies are listed 'Best First'.
Re: Dir recursion
by kvale (Monsignor) on May 07, 2004 at 07:33 UTC
    For a task like this, I would probably first see if rsync could do what I wanted.

    If you want to write it in Perl, it would be useful to use or steal code from Net::FTP::Recursive which already handles recursive gets, puts and listings. I don't see an option to prevent overwrite, but it shouldn't be too hard to hack it in; other filters are already available as examples.


Re: Dir recursion
by Hena (Friar) on May 07, 2004 at 09:34 UTC
    I would suggest taking look at mirror. That's ftp mirror software and it handles recursions as well.
Re: Dir recursion
by ozone (Friar) on May 07, 2004 at 08:17 UTC
    I agree with the previous comment, but would like to comment on the problem anyway ...

    if (-f "$dir/$file") { print "SEND $dir/$file to ftp server\n"; &Put_File($dir, $file); } else {
    This test doesn't make sense in the context of what you are doing. If I'm seeing it correctly, this check should always pass, because you got the filename from the readdir just above. I think you possibly meant to check that the file exists on the remote side?


    UPDATE: now I see what's being done. D'oh!

      Thanks you for your comments, however, I am checking if $file is a file (it could be a directory), if it is a file I do an FTP put (&Put_File I check if the file exists on the remote in that sub) however if it is a dir I check the remote to see if that dir exists on the remote and then I run the Process_Struct again.
      Of all the things I've lost in my life, its my mind I miss the most.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://351377]
Approved by kvale
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2021-02-26 22:06 GMT
Find Nodes?
    Voting Booth?

    No recent polls found