in reply to Re^11: transfer a file via SFTP
in thread transfer a file via SFTP

The remote machine is Windows 2003 and doesn't have /var/log/messages, but this is a local problem.
This script cannot handle the path to the remote directory.
Any idea howto correct this script?

Replies are listed 'Best First'.
Re^13: transfer a file via SFTP
by ig (Vicar) on Jul 31, 2009 at 21:32 UTC

    In your previous post you said that when the destination path was "TEST.txt" the transfer was successful, but when you changed the path to "/sftp/test/TEST.txt" it failed. Given the destination system is Windows, I wonder if the ssh server on your Windows system doesn't accept "/" as a directory separator. Maybe it would work if you specified the path as "\\sftp\\test\\TEST.txt", and maybe you should specify the drive: "C:\\sftp\\test\\TEST.txt".

    You might try running process monitor on the destination system to see what the ssh server is doing when the file transfer is attempted. I guess you will see it attempt to access some file or folder with a permission error. Maybe you will see that it is not the folder you think it is (e.g. on a different drive).

      First of all THX again for your help.
      The path to the remote directory is /HOME
      This is not a problem of a remote server.
      If I change this script like below, then the file will be sent without problems, but it will be renamed from TEST.txt to NEW.txt.
      I must send a file with original name.
      How to change this script now?
      #!/usr/bin/perl -w use strict; use warnings; use File::Copy; use File::Find; use Net::Netrc; use Net::SFTP; use MIME::Lite; use Getopt::Std; use Mail::Sender; my $from = '/srv/*.txt'; my $to = '/HOME/NEW.txt'; my $server = 'X.X.X.X'; my $user = 'user'; my $sftp; my %args = ( ssh_args => { user => 'user', identity_files => [ '/home/.ssh/id_r +sa' ], protocol => '2,1', debug => 1, } ); my $linux = "admin\@domain.net"; my $recipient1 = "recipient1\@domain.net"; my $recipient2 = "recipient2\@domain.net"; my $recipient3 = "recipient3\@domain.net>"; # write a log BEGIN { use CGI::Carp qw(carpout); my $errorlog = "/srv/logs/transferlog.txt"; open(LOG, ">$errorlog") or die("Unable to open $errorlog: $!\n"); print LOG "Errors:\n"; carpout(*LOG); } # create backup subfolder my @dt = localtime; my $subfolder_name = ((((1900 + $dt[5]) * 100 + 1 + $dt[4]) * 100 + $d +t[3]) * 100 + $dt[2]) * 100 + $dt[1]; mkdir "/srv/OUT/$subfolder_name" or die "$subfolder_name: $!"; foreach my $from (</srv/*.txt>) { # sftp file transfer $sftp = Net::SFTP->new($server, %args) or die "could not open connecti +on to $server\n"; $sftp->put($from, $to) or die "could not upload $from\n"; # move files to the backup directory unless(move("$from", "/srv/OUT/$subfolder_name")) { print STDERR "Oops! Couldn't move the file: $!"; } move "/srv/logs/transferlog.txt", "/srv/OUT/$subfolder_name"; sleep (1 * 5) } # send a mail if transfer completed my $sender = new Mail::Sender {smtp => 'localhost', from => $linux}; $sender->MailFile({to => "$recipient1, $recipient2, $recipient3", subject => 'data transfer', msg => 'data transfer should be completed', file => "/srv/OUT/$subfolder_name/transferlog.txt"}); exit;

      greetings
      cc

        Maybe the following will work for you

        use strict; use warnings; use File::Copy; use File::Find; use Net::Netrc; use Net::SFTP; use MIME::Lite; use Getopt::Std; use Mail::Sender; my $server = 'X.X.X.X'; my $user = 'user'; my $sftp; my %args = ( ssh_args => { user => 'user', identity_files => ['/home/.ssh/id_rsa'], protocol => '2,1', debug => 1, } ); my $linux = "admin\@domain.net"; my $recipient1 = "recipient1\@domain.net"; my $recipient2 = "recipient2\@domain.net"; my $recipient3 = "recipient3\@domain.net>"; # write a log BEGIN { use CGI::Carp qw(carpout); my $errorlog = "/srv/logs/transferlog.txt"; open( LOG, ">$errorlog" ) or die("Unable to open $errorlog: $!\n") +; print LOG "Errors:\n"; carpout(*LOG); } # create backup subfolder my @dt = localtime; my $subfolder_name = ( ( ( ( 1900 + $dt[5] ) * 100 + 1 + $dt[4] ) * 100 + $dt[3] ) * 100 ++ $dt[2] ) * 100 + $dt[1]; mkdir "/srv/OUT/$subfolder_name" or die "$subfolder_name: $!"; foreach my $from (</srv/*.txt>) { ( my $to = $from ) =~ s/.*\//\/HOME\//; # sftp file transfer $sftp = Net::SFTP->new( $server, %args ) or die "could not open connection to $server\n"; $sftp->put( $from, $to ) or die "could not upload $from\n"; # move files to the backup directory unless ( move( "$from", "/srv/OUT/$subfolder_name" ) ) { print STDERR "Oops! Couldn't move the file: $!"; } move "/srv/logs/transferlog.txt", "/srv/OUT/$subfolder_name"; sleep( 1 * 5 ); } # send a mail if transfer completed my $sender = new Mail::Sender { smtp => 'localhost', from => $linux }; $sender->MailFile( { to => "$recipient1, $recipient2, $recipient3", subject => 'data transfer', msg => 'data transfer should be completed', file => "/srv/OUT/$subfolder_name/transferlog.txt" } ); exit;

        You might move setup of the sftp connection outside the loop. You should be able to transfer multiple files over a single connection.

        The first time though the loop the log file will be moved but in subsequent iterations the move will fail because the log file is no longer in its original location.