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


in reply to Perl SFTP question?

You might do well to read How do I post a question effectively? and Writeup Formatting Tips. In particular, you should be wrapping code in <code> tags and try to make sure published code is runnable as written. You are clearly using modules but have not specified what modules you are using.

Based upon your syntax, I am gussing you are using the Net::SFTP module. From the module's documentation:

$sftp->ls($remote [, $subref ])

Fetches a directory listing of $remote.

If $subref is specified, for each entry in the directory, $subref will be called and given a reference to a hash with three keys: filename, the name of the entry in the directory listing; longname, an entry in a "long" listing like ls -l; and a, a Net::SFTP::Attributes object, which contains the file attributes of the entry (atime, mtime, permissions, etc.).

If $subref is not specified, returns a list of directory entries, each of which is a reference to a hash as described in the previous paragraph.

You can therefore recover the -l result by changing your key from filename to longname. Your sorting options take a little more work, since you need the complete list to sort it. I would suggest you modify your subroutine to return an array ref with the longname and mtime, and then use sort with a custom function on the returned list.

Update: As SilasTheMonk points out below, following this approach requires a closure to cache search results rather than the simple return I describe above.

Update 2: Having reread the above, the return value from an ordinary call to $sftp->ls contains all the information you need to recover your desired result (untested).

my @contents = $sftp->ls($RemoteBaseDirectory . $RemoteOutgoingDirecto +ry); my @sorted = sort {$b->{a}->mtime <=> $b->{a}->mtime} @contents; print $sorted[0]->{longname};

If the above fails, you need to look at the format of the mtime return to fix the compare.

Replies are listed 'Best First'.
Re^2: Perl SFTP question?
by SilasTheMonk (Chaplain) on Oct 06, 2009 at 21:40 UTC
    I thought about that approach but I rejected it. What exactly could you have the subroutine do? I think if you look at the source code, Net::SFTP will do nothing with the return value of the subroutine so your only option is to write it somewhere else. That is either going to be really bad and ugly or perhaps in some fascinating circumstances really elegant (but hard to understand).
      I naively assumed that the ls call returned a list of return results from the passed coderef, and having looked at the source I can't help wondering why the module writer didn't do that (the values just get dumped since it explicitly returns an empty array; I really don't understand that choice). I would say then the best choice is using a closure to export the data value. If the OP only wants the oldest value, a simple compare and drop would probably be best. Otherwise, he could use the closure to export an array of the mtime and longname values. He's already caching search results using a closure, so neither of those should be a challenge. Explicitly performing an element-by-element stat seems like excess. I will concede that it gains clarity.