http://qs1969.pair.com?node_id=190020

Preamble

I have to deal with FTP a lot... uploading and getting files, mostly from the same server & directory (where files we give to customers reside). Well, I decided to try and automate things a bit, and use Perl for this purpose.

use Net::FTP

I immediately plunged into CPAN and found this nice module, that seemed to be just what I needed. However, trying to find a good tutorial on the subject (the docs of this module are quite good, but with a tutorial it is possible to get started quicker), I was dissapointed and decided to write one, on a very basic level, for other monks.

Let's go ...

First, connecting and logging to the desired server. As I said earlier, most of the time I just need one server with one user name (and most of these times, the same directory), so I just store them in variables.
use strict; # Don't forget ! use Net::FTP; my $host = "your.favorite.server"; my $user = "user"; my $password = "password"; my $f = Net::FTP->new($host) or die "Can't open $host\n"; $f->login($user, $password) or die "Can't log $user in\n";

As simple as that... neat, huh ? Well, now that we're in, all sorts of things possible with FTP can be done. For example, getting into a directory:
my $dir = "my/favorite/dir"; $f->cwd($dir) or die "Can't cwd to $dir\n";

The most basic and useful operations are getting and putting files to/from the server. This is done with the get() and put() methods, and w/o any special options the files must reside in the directory from which your script was called. Here is the usage:
my $file_to_get = "something"; my $file_to_put = "other something"; $f->get($file_to_get) or die "Can't get $file from $dir\n"; $f->put($file_to_put) or die "Can't put $file into $dir\n";

These operations will usually do for 95% of your FTP'ing, but there are more interesting things to do, and this is where Perl comes into question (what we've done so far can be automated with shell commands). For example, finding out the modification time of a file and doing something about it:
my $file_mdtm = $f->mdtm($file) or die "Can't find $file in $dir\n";

This gets the modification time in epoch seconds format. This way, it is easy to compare with dates generated by the time function. For instance:
my $file_mdtm = $f->mdtm($file) or die "Can't find $file in $dir\n"; my $five_days = 3600*24*5; # five days in seconds if (time - $file_mdtm >= $five_days) { print "$file is more than 5 days old\n"; }

We can also get a list of all files (similar to the output of 'ls') from the directory.
$, = "\n"; my @files = $f->ls; print @files, "\n";

To get a listing in the long format (of ls -l), use the dir method rather than ls.

A couple of additional tidbits

When you have to transfer files between different operating systems, Unix and Windows for example, you should care about Binary/ASCII transfer. ASCII should be used to transfer text files (more technically - files where lines and the breaks between them are important), which includes Perl source code, POD, etc. and all the rest is transferred with Binary. To toggle between Binary and ASCII mode use:
$f->ascii(); $f->binary();

You should see the documentation of Net::FTP for more modes (EBCDIC, for one), but most chances are you will only need these two. One more thing... Messages from the FTP server are captured in the $f->message variable. They may be error messages, but also confirmation messages (like 'CWD command successful'). One exception though is the message from the constructor new(). If it fails, the error message is recorded in $@. So, we can also open the connection like this, for a more descriptive error message:
my $f = Net::FTP->new($host) or die "Can't open $host: $@\n";

Conclusion

I hope you enjoyed this short tour into Net::FTP and find it helpful, I certainly did ! These operations (along with the usual Perl cool way of processing things) should be enough for most of the things we have to do with FTP, but the Net::FTP module includes many more, so if your usage is really advanced, take a look at the docs.