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

Hi Monks,

I wrote a script for backup files from a server to a pc regularly. But it seems not work. Below is the code:
#!/usr/bin/perl use strict; use warnings; use Win32::DriveInfo; use File::Path; use Net::FTP; ## define variables # my %parameters; my $remote_server ; my $username ; my $password ; my $backup_dir ; my $backup_file_numbers ; my $driver_freespace ; my $remote_backup_dir ; my $remote_file ; my $file_name; my $new_directory; # Read parameters from CFG ## sub read_par { open (STDERR, ">>backup_err.log") or die "can't redirect STDERR $!\n"; print STDERR "Backup begin at: ",scalar localtime,"\n\n"; open (CFG,"<auto_backup.ini") or die "Can't open config file $!\n"; while (<CFG>) { chomp; s/#.*//; s/^\s+//; s/\s+$//; next unless length; my ($var, $value) = split(/\s*?=\s*?/, $_, 2); $parameters{$var} = $value; } close CFG; $remote_server = $parameters{'remote_server'} || "192.168.0.1"; $username = $parameters{'username'} || "dgc2000"; $password = $parameters{'password'} || "Dgc2000"; $backup_dir = $parameters{'backup_dir'} || 'D:\backup'; $backup_file_numbers = $parameters{'backup_file_numbers'} || '20'; $driver_freespace = $parameters{'driver_freespace'} || '5'; $remote_backup_dir = $parameters{'remote_backup_dir'} || "/usr/backup" +; $remote_file = $parameters{'remote_file'} || "dgc2000_backup.tar"; } #check driver space # sub check_space{ my $freebytes = Win32::DriveInfo::DriveSpace('d'); die scalar localtime,": Backup will be forcibly stopped due to the ins +ufficent system space, please check driver and set it free. \n\n" if +$freebytes < $driver_freespace; } ## check directory and create new. # sub check_dir{ opendir(DIR, $backup_dir) or die "can't opendir $backup_dir:$!"; my @dots = sort {[stat($a)]->[9] <=> [stat($b)]->[9]} grep {!/\.$/ && +-d} map {join '\\', $backup_dir,$_} readdir(DIR); if (@dots > 1) { map {rmtree($_)} [@dots[1..$#dots]]; } } # create new directory sub create_dir{ my $localtime = scalar localtime; $localtime =~ s/:|\s/_/g; $new_directory = join ('\\',$backup_dir,$localtime); mkpath($new_directory) or die "error!!\n $!"; } # create ftp connection and fetch file. # sub fetch_file { my $ftp = Net::FTP->new($remote_server) or die "Cannot connect to $rem +ote_server: $@"; $ftp->login($username, $password) or die "Cannot login",$ftp->message; print $remote_backup_dir; $ftp->cwd($remote_backup_dir) or die "Cannot change working directory +", $ftp->message; $ftp->binary; $ftp->get($remote_file, $remote_file, $new_directory) or die "get fail +ed", $ftp->message; $ftp->delete($remote_file) or die "Can't delete", $ftp->message; $ftp->quit; die "backup end successfully at: ",scalar localtime,"\n\n"; } sub init { read_par(); check_space(); check_dir(); } sub backup { create_dir(); fetch_file(); } init(); backup(); __output__ Backup begin at: Tue Sep 4 12:33:04 2007 get failed'REST D:\backup\Tue_Sep__4_12_33_04_2007': command not under +stood.
It seems be lead by windows path. But I can't confirm it. Any body could point out a right way to solve this problem? And, after passing by this issue, I'd also like to learn other backup perl snippets to improve my skills.

Thanks in advance!

I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

Replies are listed 'Best First'.
Re: Net::FTP can't fetch file to local directory?
by hossman (Prior) on Sep 04, 2007 at 05:37 UTC

    I have not used Net::FTP in years, i remember nothing about it's API ... but sincei was bored i skimed your post, saw that the error was coming from the "get" method and read the perldocs. it appears you are calling it incorrectly -- it can take 3 args, and the third arg is refered to in the docs as "WHERE" but it is not a directory name...

    If WHERE is given then the first WHERE bytes of the file will not be transferred, and the remaining bytes will be appended to the local file if it already exists.

    ...The error message being returned seems to be the FTP server complaining that it can't understand the "REST" command since it specifies a string instead of an int for the number of bytes to skip (a quick google search indicates that i am probably correct, "REST" is hte low level FTP command indicating that the next command only wants the "rest" of the file after so many bytes.

      Hi, hossman comments are right! Third argument is Resume option (i.e. to download a partial file) I have worked extensively in Net::FTP module, I hope the below changes will work. $ftp->get($remote_file, "$new_directory/$remote_file");
      Gopal
Re: Net::FTP can't fetch file to local directory?
by Gangabass (Vicar) on Sep 04, 2007 at 06:31 UTC

    So you need to

    chdir($new_directory);

    in create_dir()
    and use only

    $ftp->get($remote_file) or die "get fail +ed", $ftp->message;