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

I have two nodes that are set up with mutual RSA keys. I can SSH and SFTP freely between them, bilaterally, password-less.I can also SFTP between then with Perl Net::SFTP using host and user and pass.

Now I want to add Foreign, and transmit between them without a password. I'm currently trying:

my $ftph; eval { $ftph = Net::SFTP::Foreign( "$user\@$host", more=>'-v', autodie=>0 ); };
after this step, $ftph is undef, and $! = 'Inappropriate ioctl for device'. And of course $ftph->error is undef as well.

If I try sftp user@host at the commandline, the SFTP connection is made successfully with no password, and it drops to the SFTP> prompt.

All of the examples I can find using ::Foreign , as well as the metacpan page, pretty much just start with this same expression, more or less. But I wonder, am I suppposed to establish an SSH pipe first with Perl BEFORE this step, but the examples don't show that step? I did see some examples that had use IO::Pty; , but there was no further calls to that class before the Net::SFTP::Foreign line.

Without the eval {} , the step dies with no message at all.

I also added $Net::SFTP::Foreign::debug = -1; but it didn't seem to produce any additional output.

Advice, tips, and guidance are most appreciated.

Replies are listed 'Best First'.
Re: trying to get Net::SFTP::Foreign to work
by kcott (Archbishop) on Apr 27, 2023 at 17:13 UTC

    G'day misterperl,

    my $ftph; eval { $ftph = Net::SFTP::Foreign( "$user\@$host", more=>'-v', autodie=>0 ); };

    That appears to have a number of problems:

    • You've omitted the new() method.
    • Your argument, "$user\@$host", doesn't agree with the documentation.
    • The eval is superfluous.

    After reading Net::SFTP::Foreign, I'm pretty sure you want something more like this:

    my $ftph = Net::SFTP::Foreign::->new($host, user => $user, ...);

    Alternatively, you could collect arguments into a hash, perhaps based on user options, and then supply that hash as the sole argument to new(). Something like this:

    my %args = (host => $host, user => $user); push @{$args{more}}, '-v' if $opt_verbose; $args{autodie} = $opt_autodie; my $ftph = Net::SFTP::Foreign::->new(%args);

    If you're wondering why I appended :: to Net::SFTP::Foreign, read "perlobj: Invoking Class Methods".

    — Ken

Re: trying to get Net::SFTP::Foreign to work
by choroba (Cardinal) on Apr 27, 2023 at 16:53 UTC
    Where did ->new from the synopsis go?

    When eval fails, check $@.

    my $ftph; eval { $ftph = Net::SFTP::Foreign( "$user\@$host", more=>'-v', autodie=>0 ); 1 } or die $@;
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: trying to get Net::SFTP::Foreign to work
by salva (Canon) on Apr 30, 2023 at 12:22 UTC
    Net::SFTP::Foreign->new() does not die on failure. You need to call the error method afterwards:
    $sftp = Net::SFTP::Foreign->new("$user\@$host"); $sftp->error and die "unable to connect to remote host: " . $sftp->err +or;