http://www.perlmonks.org?node_id=860690

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

Good Morning Monks, I have a couple of sftp related questions... first, because i couldn't get Net::SFTP installed correctly i went the system call route which is working for me,but i can't seem to capture the error from STDOUT when no file is found. This is preventing me from retrying when the error message is: "Couldn't stat remote file: No such file or directory" which i know i'm getting because it's in the STDOUT file after i run my code. I can't seem to check STDOUT for the message while it's still open. Is there a way to do this? A snippet of my code is as follows

open STDOUT,">$log" || die "Cannot open log forwriting.!"; open STDERR, ">&STDOUT" or die "Can't dup stdout"; @ret = `sftp $user\@$server <<EOF cd $srcdir $cmd $srcfile $tgtfile bye EOF`; while (<STDOUT>) { print "inside STDOUT and row is $_\n"; print "err is $_ ...retrying\n" if /No such file/; }

How can i check the STDOUT for the "No such file" error message that is in the STDOUT file?

Secondly, I'd prefer to use the Net::SFTP module. I believe it's a 3 step process where: 1) the target server needs my pub.key appended to it's authorized_keys file (which it does) 2) i need to install the Net-SSH-Perl-1.34.tar module. 3) i need to install the Net-SFTP-0.10.tar. Are these the 3 steps that need to occur? I'm having issues installing the module and getting it to work, so perhaps i'm missing a step or another dependent module? Any help would be greatly appreciated. thanks

Replies are listed 'Best First'.
Re: Having trouble getting sftp to work
by perlpie (Beadle) on Sep 19, 2010 at 15:50 UTC

    There are at least a couple of questions here...

    1. How do I capture STDERR from a shell command?
    2. How do I install NET::SFTP?

    First, STDERR. There are multiple ways to do it. As you've already seen, you'll want to play with file descriptors. This text assumes the presence of a simple script in the same directory:

    #!/usr/bin/perl for (1 .. 10) { print "printing $_\n"; warn "warning $_\n"; }

    If you want both STDOUT and STDERR then you can merge them together and check the combined output.

    If you don't care about STDOUT, you can just capture STDERR instead and throw away STDOUT.

    If you want both separately, your best bet is probably to redirect STDOUT to one file and STDIN to another file, then read them in.

    This is also a FAQ, and the FAQ provides different answers. See How can I capture STDERR from an external command?. There are also CPAN modules which provide interfaces for interacting with other processes.

    OK, enough about that. Your other question was how to install NET::SFTP. Your best bet here is to let a CPAN client do the lifting for you. Read a bit and see which of the following might work for you... CPAN, CPANPLUS, App-cpanminus.

Re: Having trouble getting sftp to work
by zentara (Archbishop) on Sep 19, 2010 at 16:28 UTC
    I'm having issues installing the module and getting it to work, so perhaps i'm missing a step or another dependent module?

    This is a known problem with the older sftp and SSH-Perl modules. To fix alot of those problems, the Net::SSH2 module was developed. See A little demo for Net::SSH2 for an example of sftp and shell usage within the Net::SSH2 module.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: Having trouble getting sftp to work
by Khen1950fx (Canon) on Sep 19, 2010 at 16:27 UTC
    Here's a couple of examples. The first script logs and runs the second script which uses Net::SFTP.
    #!/usr/bin/perl use strict; use warnings; open(LOG, '>', 'LOG_FILE') or die "Can't open stdout: $!"; open(CMD, 'perl sftp_script.pl'); open(STDERR, '>&', STDOUT) or die "Can't redirect stderr: $!"; open(STDERR, '>', 'LOG_FILE') or die "Can't redirect stderr: $!"; print "LOG_FILE\n"; while (<CMD>) { print_stuff ($_); } sub print_stuff { my ($line) = @_; print LOG $line; print $line; } close(CMD) or die "close CMD failed: $!"; exit 0;
    #sftp_script.pl
    #!perl use strict; use warnings; use Net::SFTP; my $host = 'localhost'; my $user = 'user'; my $password = 'password'; my %args = ( user => $user, password => $password, port => 22, debug => 1, ); my $local = '/path/to/some/file'; my $remote = '/path/to/remote_dir/file'; my $sftp = Net::SFTP->new($host, %args); die "Can't put file: $!\n" unless $sftp->put($local, $remote); close $local;
    It's a one-step process for installing Net::SFTP. Just do cpan Net::SFTP

    Update: To install Net::SSH::Perl, do it manually as:

    perl Makefile.PL machine=none make install
Re: Having trouble getting sftp to work
by salva (Canon) on Sep 19, 2010 at 17:16 UTC