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

I have a ftp script where I changed from get to put. It runs on the local server and suppose to do a listing of all files in that directory. Afterwords, it's suppose to read the files into a list and do a put $name to the destination host. But I can't seem to figure out how to do a local directory listing once you are in a ftp session in unix. The manual says !ls -l but perl doesn't recognize it. Please help! Thanks
#!/usr/bin/perl use Net::FTP; use File::Listing qw(parse_dir); $host = 'ServerName'; $path = '/home/'; $ftp = Net::FTP->new($host, Timeout => 1800) or die "Cannot contact $h +ost: $!"; $ftp->login('ID', 'PWD') or die "Cannot login ($host):" . $ftp->messag +e; $ftp->cwd($path) or die "Cannot change directory ($host):" . $ftp->mes +sage; #@Files = $ftp->ls('-lR'); @Files = $ftp->!ls ('-l'); #$ftp->binary(); #$ftp->ascii(); foreach $file (parse_dir(\@Files)) { my($name, $type, $size, $mtime, $mode) = @$file; $ftp->put("$name") or warn "Could not get $name, skipped: $!"; } $ftp->quit; exit;

Replies are listed 'Best First'.
Re: ftp put problem!
by runrig (Abbot) on Jul 29, 2008 at 20:03 UTC
    Why do you need to do a local directory listing through ftp? Just use glob, or opendir/readdir. If you need a remote directory listing, then you'll need to use the ftp connection.
      Thanks for your input. I'm fairly new to perl so i'm not really familiar w/ opendir. Once you get the opendir and readdir, how would you use a string so you can write a $ftp>put statement? thanks,
        The same as in your code (though you don't need the quotes, and ftp error messages are in the message() method, not $!):
        $ftp->put($name) or warn "Could not put $name, skipped: ".$ftp->messag +e();
        Note that readdir returns the file name without the path, so before putting you will have to either chdir to the directory, or prefix the directory name onto the string you pass to put().
Re: ftp put problem!
by jrsimmon (Hermit) on Jul 29, 2008 at 20:25 UTC
    You don't even nead readdir if all you want is a listing. That's what the backtick operator is for:
    #!/usr/bin/perl use Net::FTP; use File::Listing qw(parse_dir); $host = 'ServerName'; $path = '/home/'; $ftp = Net::FTP->new($host, Timeout => 1800) or die "Cannot contact $h +ost: $!"; $ftp->login('ID', 'PWD') or die "Cannot login ($host):" . $ftp->messag +e; $ftp->cwd($path) or die "Cannot change directory ($host):" . $ftp->mes +sage; #@Files = $ftp->ls('-lR'); @Files = 'ls -l'; #@Files = `ls -l $path' if $path is what you want a listing of #$ftp->binary(); #$ftp->ascii(); foreach $file (parse_dir(\@Files)) { my($name, $type, $size, $mtime, $mode) = @$file; $ftp->put("$name") or warn "Could not get $name, skipped: $!"; } $ftp->quit; exit;
      The script seems to run fine but the files are not transferred over to the remote server. It's suppose to do a ls -l then grab the files, parse and ftp. thanks
      #!/usr/bin/perl
      use Net::FTP;
      use File::Listing qw(parse_dir);
      $host = 'hostname';
      #$path = 'path/';
      $ftp = Net::FTP->new($host, Timeout => 1800) or die "Cannot contact $host: $!";
      $ftp->login('ID', 'pwd') or die "Cannot login ($host):" . $ftp->message;
      #$ftp->cwd($path) or die "Cannot change directory ($host):" . $ftp->message;
      #Files = `dir *.txt`;
      #$ftp->binary();
      #$ftp->ascii();
      @Files= `ls -lR`;
      foreach $file (parse_dir($Files))
      {
      my($name, $type, $size, $mtime, $mode) = @$file;
      $ftp->get ($name) or warn "Could not get $name, skipped: $!";
      }
      $ftp->quit;
      exit;
        You are get()'ing the files...I thought you wanted to put()?
Re: ftp put problem!
by jethro (Monsignor) on Jul 29, 2008 at 20:22 UTC
    runrig has answered everything you wanted to know about ftp but were afraid to ask ;-). I'll try to answer the last detail:

    I'm pretty sure that there is no method named '!ls'. I would bet though that there is a method named 'lls', short for 'local ls'.

    UPDATE: Checked Net::FTP and there is no lls. With "manual" you probably meant a manual page of ftp and not the manual page of Net::FTP. That is not the same.

    UPDATE OF THE UPDATE: ++Fletch for the I-should-have-known-but-did-not explanation

      More likely he's confused Net::FTP with the manual for the command line ftp client which like many *NIX utilities supports running shell commands by prefixing them with a !.

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

Re: ftp put problem!
by Khen1950fx (Canon) on Jul 29, 2008 at 22:43 UTC
    Addressing just the ls -lR problem, I took a recent script and modified it to get ls to work:

    #!/usr/bin/perl use strict; use warnings; use Net::FTP::File; use constant HOST => 'ftp.cpan.org'; use constant DIR => '/pub/CPAN'; use constant FILE => 'README'; my $ftp = Net::FTP->new( HOST, Timeout => 1, Debug => 1, Passive => 1) or die "Cannot contact HOST: $@\n"; $ftp->login('anonymous'); $ftp->cwd(DIR); $ftp->binary; print $ftp->ls('-lR'); $ftp->quit;

    Does this help?

Re: ftp put problem!
by eosbuddy (Scribe) on Jul 29, 2008 at 23:31 UTC
    I believe your problem is due to permissions. The user that tries to do the ftp login should have permission to write to the folder in $path (i.e. /home/) If you're ftp'ing in as user bbi, and path set to /home/bbi should work... but /home/ may not.