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

I'm trying to get file information off an SFTP site, to ultimately move the files locally. My plan was to connect using pwd authentication, list the files in a specified directory, and for each result, determine if it is a file. If so, get the file and place it locally.

I can connect and get, but am having fits trying to figure out how to process the directory listing.

Below is the code I have. I have tried calling a subroutine from in sftp->ls and other things. No luck. Any suggestions would be welcome.

#!/var/opt/pgpdba/perl/bin/perl #use strict; use Net::SFTP; use Net::SFTP::Attributes; use Logger; use Platform; use Getopt::Std; use File::Basename; $0 =~ s/^.*(\/|\\)//; # Strip a path if it is exists my $root = $0; $root =~ s/\..*$//; # Clean up script name my $LOG_FILE = "./${root}.log"; getopts('hr:l:'); print_usage_and_quit() if ($opt_h); my $CREDFILE = "./user.txt"; my $host=""; my $user=""; my $password=""; my $rdir=$opt_r; my $ldir=$opt_l; openlog("$LOG_FILE"); load_credentials(); my $sftp = Net::SFTP->new($host, user => $user, password => $password, debug => 1); #my $attrs = Net::SFTP::Attributes->new(Stat => [ stat "./session_moni +tor.sql" ]); #my $size = $attrs->size; #print "$size\n"; #exit; $sftp->ls($rdir,sub{print "$_[0]->{filename}\n"}) ; #@listing = $sftp->ls($rdir,); #foreach(@listing) #{ # print "$_\n"; #}*/ #$sftp->do_lstat("oc") ; #$sftp->get("$rdir/*", "$ldir/*"); #$sftp->put("bar", "baz"); sub getfile ($filestuff) { if ($_[0]->{filename} ne '.' && $_[0]->{filename} ne '..' && $ +_[0]->{filename} ne 'processed') { print "1 - $filestuff\n" #$sftp->get("$rdir/".$_[0]->{filename}, "$ldir/".$_[0] +->{filename}); } } sub load_credentials { open (CREDFILE1, "<$CREDFILE") or quittext_opc "Can't open credentials file $CREDFILE\n" +, $AP_CNA, $SEV1, $GRP3, "1010", $STAT1; #die "Can't open credentials file $CREDFILE\n"; while (<CREDFILE1>) { # next if /^\s*(?:#|$)/; + # ignore comments/ blank lines chomp; my @fields = split /:/; if ($fields[0] eq 'user') { $user=$fields[1]; } if ($fields[0] eq 'pwd') { $password=$fields[1]; } if ($fields[0] eq 'host') { $host=$fields[1]; } } return 0; }

I didn't include the print_usage_and_quit sub....

Edited by davido: Added readmore tags.

Thanks, Jim

Replies are listed 'Best First'.
Re: using sftp to get file information for processing
by Tomte (Priest) on Aug 05, 2004 at 18:14 UTC

    This part of your code works here:

    [2005]tom@margo ~ $ perl use Net::SFTP; use Net::SFTP::Attributes; my $sftp = Net::SFTP->new('test2.dievision', user => 'MYNAME', passwor +d => 'MYPASSWORD', debug => 1); $sftp->ls('/(some/dir', sub {print STDERR "$_[0]->{filename}\n"}); 1;
    I get a whole lot of debug information, and the file-listing as expected. Changing the anonymous sub to:
    $sftp->ls('/some/dir', sub {my $attrs = $sftp->do_stat($_[0]->{filenam +e}); print STDERR $_[0]->{filename}, " ", $attrs->gid, " ", $attrs- +>size, "\n"});
    resulted in correct answers as to gid and size; are you sure the connection is working correctly?

    regards,
    tomte


    An intellectual is someone whose mind watches itself.
    -- Albert Camus

      Thanks everyone for the input. I was able to get it working very well. The only outstanding issue is the ability to capture the result of the sftp->get command. It doesn't appear to give a return code and I don't know what all the possible textual responses are from this command. Does anyone have any ideas?

      Just for your viewing, here is the code now. Ignore the junk around the get. I just haven't cleaned up stuff that doesn't work (but doesn't hurt).

      Thanks, Jim
Re: using sftp to get file information for processing
by waswas-fng (Curate) on Aug 05, 2004 at 18:16 UTC
    From the psftp script example included with the source:
    sub process_ls { my($shell, @arg) = @_; $shell->mywarn("usage: ls [path]"), return unless @arg < 2; $shell->{sftp}->ls($arg[0] || $shell->{pwd}, sub { print $_[0]->{longname}, "\n" }); }
    If you look at that script it should give you a little more insight on how to use the functions.


    -Waswas
Re: using sftp to get file information for processing
by Plankton (Vicar) on Aug 05, 2004 at 17:11 UTC
    Maybe you could use Net::SSH to do the remote 'ls'?

    Plankton: 1% Evil, 99% Hot Gas.