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

Walking a directory tree with net:FTP:find

by bdunbar (Initiate)
on May 31, 2012 at 14:17 UTC ( #973535=perlquestion: print w/replies, xml ) Need Help??
bdunbar has asked for the wisdom of the Perl Monks concerning the following question:

Learning PERL, needing a real-world example to hurl myself upon, I picked a problem I've already resolved using BASH.

What I need: Login to an FTP server. Using a list of directories, move all files in that directory tree to another directory, renaming to standard.

So this

/test1/in/foo.edi /test1/in/dir/bar.edi

becomes this

/composite/test1_YYYYMMDDHHSS_foo.edi /composite/test1_YYYYMMDDHHSS_bar.edi

I've got the move and rename down. For 'a' directory.

Where I appear to be stuck is getting that sucker to walk the directory tree.

It's executing without error, I just don't see where I've gone wrong, why it's not calling wanted subroutine.

#!/usr/bin/perl -s use strict; use warnings; use diagnostics; use Net::FTP::Find; my($host) = ""; my($user) = "redacted"; my($password) = "redacted"; my($ftpdir) = "/test1/in"; my $ftpfind = Net::FTP::Find->new($host) or die "Can't open $host: $@\ +n"; $ftpfind->login($user, $password) or die "Can't log $user in: $ftpfind +\n"; $ftpfind->cwd($ftpdir) or die "Can't cwd to $ftpdir: $ftpfind\n"; print "this is ftpfind $ftpfind\n"; # sanity check so I know it's doin +g _something_ $ftpfind->finddepth (\&wanted, "/test1/in"); sub wanted { print "hello"; print $_; }
$ ./ this is ftpfind Net::FTP::Find=GLOB(0x10083ce10) $
edited to add shell type and variable $ftpdir. Thanks, dulwar.

Replies are listed 'Best First'.
Re: Walking a directory tree with net:FTP:find
by thundergnat (Deacon) on May 31, 2012 at 17:06 UTC

    The obvious question is: "Are you sure that the directory '/test1/in' exists and the ftp user has read permissions to it?". Should the directory be "./test1/in" or "~/test1/in" or maybe "test1/in"? I don't see anything glaringly wrong with the code in general.

      The obvious question is:

      Good question. The answer is 'yes'.
      ftp Connected to 220 Redacted FTP service. 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> cd /test1/in 250 Directory successfully changed. ftp> ls 229 Entering Extended Passive Mode (|||55795|). 150 Here comes the directory listing. -rw-rw-r-- 1 227 101 308 May 29 20:47 TOMEN_12042000 +44.EDI -rw-rw-r-- 1 227 101 305 May 29 20:47 TOMEN_12042000 +45.EDI -rw-rw-r-- 1 227 101 308 May 29 20:47 TOMEN_12042000 +49.EDI drwxr-xr-x 2 0 0 3 May 29 21:47 one drwxr-xr-x 2 0 0 2 May 29 21:42 two 226 Directory send OK.

      Should the directory be

      I'll run over and give that a shot. Thanks.

      I tried with "./test1/in", "~/test1/in", "/", and finally " ".

      Same result as noted in parent

      Finally I extracted the source from the article (to ensure it was clean, free of any krep that might have crept in while I've been thrashing) to a new file, saved to disk, made it executable. Same problem.

      Threw in a directory name that does _not_ exist
      $ftpfind->finddepth (\&wanted, "/namethatdoesnotexist"); sub wanted { print "hello"; print $_; }

      Same Error

      It is possible that when CPAN compiled Net::FTP::Find it ... got something wrong, screwed up the bits?

        I doubt if it got corrupted by the installation process; it's a pure perl module so should be pretty straight forward.

        I'm working on a Windows machine w/Active perl at the moment and was moderately surprised to find there don't seem to be any ppm packages for that module generally available.

        Ah well, I went ahead and installed it manually and tried (a suitably modified version of) your script and am getting the same results locally.

        In poking around a bit, it looks to me like a bug in Net::FTP::Find::Mixin. Specifically, in line 116:

        if ($depth == 0) { next if $_ ne '.'; # <-- line 116 $_ = $directory; }

        The logic seems backwards; I believe it should be eq not ne.

        if ($depth == 0) { next if $_ eq '.'; $_ = $directory; }

        With that change made locally it works as I would expect... And on inspection of the Net::FTP::Find::Mixin CPAN page, there is an open bug report filed about this very problem, (Though it doesn't mention the above solution)

Re: Walking a directory tree with net:FTP:find
by dulwar (Monk) on May 31, 2012 at 17:11 UTC
    $ftpdir is not set in your script. You should be getting a compile time error from strict.

      No, it is there.

      It did not survive the cut / paste from terminal to browser. I'll edit so it's correct.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://973535]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2018-03-20 07:09 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (248 votes). Check out past polls.