http://qs321.pair.com?node_id=124343
Category: FTP Stuff
Author/Contact Info Tommy Rohde aka. enaco
Description:

Script to get same set of files from multiple hosts saving them as hostname.filename using a seperate host and file list (entries are seperated by a newline) so people wont mess up the code by misstake adding hosts or files to get.
I use it for backup

#!/usr/bin/perl
#
# Entries in the file and host list should be seperated with
# a new row. spaces or other signs will make the script fail.
# You can use comments in the host and file lists if you put
# a '#' sign in the beginning of the line.
#
use Net::FTP;
use strict;

my $usage = "$0 filelist hostlist username password directory\n";
my $filelist = $ARGV[0] or die "$usage";
my $hostlist = $ARGV[1] or die "$usage";
my $username = $ARGV[2] or die "$usage";
my $password = $ARGV[3] or die "$usage";
my $home = $ARGV[4] or die "$usage";
my $debug = 5;
our $nr1 = 0;

open(FilesToGet, $filelist)
or die "can't open filelist $filelist: $!\n";

open(HostsToGet, $hostlist)
or die "can't open hostlist $hostlist: $!\n";

my @hostarr = <HostsToGet>;
chomp @hostarr;
my $hostarrnr = @hostarr;

my @filearr = <FilesToGet>;
chomp @filearr;
my $filearrnr = @filearr;

@hostarr = grep !/^#/, @hostarr;
@filearr = grep !/^#/, @filearr;

my $filearrnr = @filearr;
my $hostarrnr = @hostarr;

print "\nHosts: $hostarrnr\n";
print "Files: " . ($filearrnr * $hostarrnr) . "\n\n";

sub ftpbackup {
    if (my $pid = fork) {
        print STDERR "Connecting to $hostarr[$nr1]\n" if $debug > 3;
        my $ftp = Net::FTP->new($hostarr[$nr1]);
        $ftp->login($username, $password);
        $ftp->cwd($home);
        for (my $nr2 = 0; $nr2 < $filearrnr; $nr2++) {
            print STDERR "Getting $filearr[$nr2]\n" if $debug > 3;
            $ftp->get($filearr[$nr2],("$hostarr[$nr1]." . $filearr[$nr
+2]));
        }
        $ftp->quit;
        exit;
    }
}

for ($nr1 = 0; $nr1 < $hostarrnr; $nr1++) {
    ftpbackup();
}
Replies are listed 'Best First'.
Re: ftpbackup
by mandog (Curate) on Nov 09, 2001 at 20:58 UTC
    A few small things

    It looks you are testing for comments twice.

    for (my $nr = 0; $nr < $filearrnr; $nr++) { splice (@filearr, $nr, 1) if ($filearr[$nr] =~ /^#/) }
    and
    next if ($filearr[$nr] =~ /^#/);
    You might consider the more perlish, more compact construction
    foreach my $nrl (@hostarr){}
    instead of:
    for (my $nr1 = 0; $nr1 < $hostarrnr; $nr1++)

    If you wanted to be moderately fancy you could  fork() each server's FTP session. That way your script wouldn't hang waiting for an unreachable host to time out



    email: mandog

      Thanks for the pointers mate.

      Il hack something up tonight, this is getting more fun the more you learn :o)

Re: ftpbackup
by neilwatson (Priest) on Nov 09, 2001 at 18:32 UTC
    I realise the point of Perlmonks is to promote perl but wouldn't the user be far better off using rsync?

    I won't even go into the dangers of ftp versus ssh's sftp.

    Neil Watson
    watson-wilson.ca

        Rsync on a unix box should be able to synce to a windoze ftp or ssh server. As for a windoze client. You'd have to check the Website.

        Neil Watson
        watson-wilson.ca

      I know what you mean, point taken.

      This script was primarly built for developing perl skills, there are more then 5 better ways that i can think up right now not using perl to solve this, and security.. well this script was intended to be used on a closed net and our provider of the system i backup does not allow me installing openssh etc.

      Thank you all for the tips and pointers.
Re: ftpbackup
by sparkyichi (Deacon) on Dec 21, 2001 at 22:44 UTC
    Very nice code. One thing that I noticed is that it appears that you have you set our $nr1 = 0 and for ($nr1 = 0; $nr1 < $hostarrnr; $nr1++). I think you can localize it at the beginning or localize it in your for statement then when you call you sub you can pass it to your sub like this:
    ftpbackup($nr1);
    I have learned that this is a lot more efficient and strict will look at your $nr1 variable (our makes it a global.) I hope this helps.
    I really like your program and it has helped me make a similar program.

    Sparky