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


in reply to Problem in connecting to remote unix host via Net::SSH2 from windows machine

I unable to judge weather the script actually succeeded in connecting the host and failed only in executing the the command which I have assigned for $cmd.

Yes, I think the connection has succeeded and the error is coming from the Linux host - though I doubt very much that "pwd" is in fact unknown to that host.

On Windows, I'm apparently not set-up to use the auth_keyboard authentication to my remote Linux host - instead of auth_keyboard, I use auth_pubkey.
Then, in order to get your script to work, I have to slightly alter your run_testsuite() sub to:
sub run_testsuite { my $cmd = $_[0]; my $ssh2 = $_[1]; my $chan2 = $ssh2->channel(); #$chan2->blocking(0); $chan2->exec($cmd); print "LINE : $_" while <$chan2>; $chan2->close; return 0; }
Update: Actually, your original sub works fine for me so long as I precede the call to $chan2->shell(); with $chan2->blocking(0); .

With $ssh2->debug(0), that outputs (as expected):
Executing command... ==> Running pwd LINE : /home/sisyphus test passed done 0


Maybe give that approach a go instead - if only to verify that your remote Linux host does understand "pwd".

With $ssh2->debug(1) it outputs:
Executing command... ==> Running pwd Net::SSH2::poll: timeout = 1000, array[0] libssh2_channel_open_ex(ss->session, mandatory_type, strlen(mandatory_ +type), window_size, packet_size, ((void *)0) , 0 ) -> 0x2a6e3c4 Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::getc(ext = 0) LINE : /home/sisyphus Net::SSH2::Channel::DESTROY test passed done 0 Net::SSH2::DESTROY object 0x297d73c
which is also quite correct, but confusingly verbose.

If I include $chan2->blocking(0); (presently commented out), the debugging output becomes a little less verbose:
Executing command... ==> Running pwd Net::SSH2::poll: timeout = 1000, array[0] libssh2_channel_open_ex(ss->session, mandatory_type, strlen(mandatory_ +type), window_size, packet_size, ((void *)0) , 0 ) -> 0x29ce3c4 Net::SSH2::Channel::getc(ext = 0) Net::SSH2::Channel::DESTROY test passed done 0 Net::SSH2::DESTROY object 0x28dd73c
For your script, you could try setting blocking(0) and blocking(1) to see if that makes any difference. You might also try replacing:
print $chan2 "$cmd \n";
with:
print $chan2 "$cmd\n";
And try anything else you can think of ;-)

Cheers,
Rob

Replies are listed 'Best First'.
Re^2: Problem in connecting to remote unix host via Net::SSH2 from windows machine
by salva (Canon) on Jun 12, 2017 at 08:25 UTC
    Actually, your original sub works fine for me so long as I precede the call to $chan2->shell(); with $chan2->blocking(0);

    Using non-blocking mode in that way is quite unreliable!

    The remote shell started by the shell method call runs a loop where it waits for new commands to be submitted and that's the reason why print "LINE : $_" while <$chan2> blocks; the remote shell is just waiting for a new command to arrive in order to execute it. It nevers sends the EOF which would terminate the while.

    Setting non-blocking mode causes <$chan2> to read data immediately available. So you depend on the remote command and the SSH talk on the network bringing its output faster than the perl script reading it.

    The right way to handle that is to look for the shell prompt to arrive (you have to ensure it can not appear in the command output), or to make the remote command generate its output in some way such that its end can be detected (i.e. appending some marker, preppending the length, using chunk-encoding, etc.).

      Using non-blocking mode in that way is quite unreliable!

      Thanks for pointing that out.
      The shell() method is something that I prefer to avoid and, in light of your explanation, I think I'll continue trying to avoid it.

      Cheers,
      Rob