Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Beginners guide to Net::FTP

by spurperl (Priest)
on Aug 14, 2002 at 10:10 UTC ( [id://190020]=perltutorial: print w/replies, xml ) Need Help??

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.

Replies are listed 'Best First'.
Re: Beginners guide to Net::FTP
by RMGir (Prior) on Aug 14, 2002 at 12:29 UTC
    Nice guide, ++.

    But don't forget binary!

    The version you wrote will work fine if you're running from a Unix client box to a Unix server.

    But if the client side is a Win32, Mac, or VMS box (and maybe if the server side is) you want to make sure you call

    $f->binary();
    before you do any other operations. From the perldoc
    The protocol also defines several standard translations which the file can undergo during transfer. These are ASCII, EBCDIC, binary, and byte. ASCII is the default type, and indicates that the sender of files will trans- late the ends of lines to a standard representation which the receiver will then translate back into their local representation.

    --
    Mike
      Is it possible to execute 'ls -la' via Net::FTP. I'm using the module but the server creates files that begin with a '.' and I need to see those.
Re: Beginners guide to Net::FTP
by runrig (Abbot) on Aug 14, 2002 at 17:16 UTC
    Its good that you check the status of the FTP calls, but if they do fail, you may want to include the specific error message (which many mistakenly believe is in $! but is not). On the Net::FTP->new() call, the error message is in $@, and after you have a valid Net::FTP object (e.g. $ftp), you can call $ftp->message.

    Another common mistake is to wrap the $ftp->message in quotes, e.g. $ftp->login('user','passwd') or die "Couldn't login: $ftp->message". If you do that, you'll get a very unhelpful error message :-)

      Which can always be remdied by some further wrapping. :-) $ftp->login('user','passwd') or die "Couldn't login: @{[ $ftp->message ]}"; ____________
      Makeshifts last the longest.
Re: Beginners guide to Net::FTP
by jimmcwibb (Initiate) on Nov 16, 2018 at 10:23 UTC
    I was having a major headache with Net::FTP recently on my raspberry pi. I found that this code:
    use Net::FTP; $ftp = Net::FTP->new("xxx", Debug => 1) or die "Cannot connect to host: $@"; $ftp->login("xxx",'xxx') or die "Cannot login ", $ftp->message; $ftp->cwd("xxx") or die "Cannot change working directory ", $ftp->message; $ftp->put("test.txt") or die "put failed ", $ftp->message; $ftp->quit;
    Didn't work and I got the error: 502 'PORT' command not implemented. I tried this on both Raspbian and Arch Arm. The same code worked fine from a windows box, however. On windows, I noticed that put behaved differently, putting the connection into PASV mode before transferring the file. On linux this didn't happen. I solved the issue by putting the entire connection into PASV mode (calling pasv() before put() didn't work):
    $ftp = Net::FTP->new("xxx", Debug => 1, Passive => 1) or die "Cannot connect to host: $@";
    This worked fine. Just putting this here in case someone else has the issue!
      Didn't work and I got the error: 502 'PORT' command not implemented.

      That looks like an FTP server that insists on passive mode. That's generally a good idea.

      I solved the issue by putting the entire connection into PASV mode

      That confirms this. Generally, passive mode is the prefered way to communicate with an FTP server. http://slacksite.com/other/ftp.html explains the difference between active and passive mode quite well.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Beginners guide to Net::FTP
by roffe (Initiate) on Jul 22, 2003 at 14:27 UTC
    I like the module but don't like leaving my passwd in a file that might be read by others who have root. I guess I should stick to using scp with encryption ?
      You should do that anyway, then - FTP transmits your password in the clear, so anyone who has root (or can otherwise put a NIC in promiscious mode) on any box on your LAN can sniff it. Worse, if it's a bigger network, it's not unlikely that someone can sneak into a room somewhere and plug his own laptop into your ethernet. Or such. FTP has served us well but should really be left to rest in peace - the innocent days of networking are long over.

      Makeshifts last the longest.

Re: Beginners guide to Net::FTP
by jbowshaw (Initiate) on Mar 21, 2008 at 15:24 UTC
    Even though this is a beginner topic. It would be nice to see how to use the use Net::FTP::AutoReconnect;
    function call.
     
    The reason being is because in my project I have a 3.5 gig file to download daily. If FTP resets, I would like to know the looping structure for AutoReconnect and to restart where the FTP transfer stopped because of a connection issue.
Re: Beginners guide to Net::FTP
by Anonymous Monk on Sep 13, 2002 at 17:17 UTC
    This tutorial was extremly useful and well written. Thank you very much!
Re: Beginners guide to Net::FTP
by cybear (Monk) on Jan 26, 2004 at 14:11 UTC

    - cybear I used net::ftp to update some ksh ftp scripts... I gained as much as a 62% increase in throughput.

Re: Beginners guide to Net::FTP
by Anonymous Monk on Sep 03, 2004 at 09:39 UTC
    Hi,... I have trouble using net::ftp when i'm behind proxy... I use the option Firewall => 'proxy:port' but still can't make it... it returned unknown number error. anybody can help me?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perltutorial [id://190020]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2024-03-19 02:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found