Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Is it possible to see what Net::OpenSSH is doing?

by walkingthecow (Friar)
on Jun 12, 2013 at 10:50 UTC ( #1038427=perlquestion: print w/replies, xml ) Need Help??
walkingthecow has asked for the wisdom of the Perl Monks concerning the following question:

Basically, what I am trying to accomplish here is the ability to see Net::OpenSSH log into a remote system, run commands (viewing STDOUT/STDERR from these commands), and then exit. I can easily connect to the system, capture STDERR/STDOUT, and then print them. But I'd really like to see what is happening as it is happening as if I was sitting there at my terminal typing the commands myself.

Let me try to be a bit more specific. What I'd really like is for Net::OpenSSH to spawn a shell (/bin/bash), ssh to remote server and run commands. I'd be looking first at a localhost prompt, then the ssh connection ('localhost # ssh remote_server'), possible a password prompt and the interaction that happens there (if password => 'pass' is used when creating object), and then the commands as they are passed on the remote shell and the remote prompt as well.

I haven't included any code here because I have no idea if it's even possible, thus no idea really where to start. I did create a Net::OpenSSH object and used Expect to create an interactive terminal, but I still only ended up with output... As well, I'd really rather not use Expect for this if I don't need to (i.e., the commands themselves are not interactive).

#!/usr/bin/env perl + use strict; + use warnings; + use Net::OpenSSH; + use Expect; + + my $timeout = 20; + my $ssh = Net::OpenSSH->new('walkingthecow@remote_host', password => ' +PkDDaDoES$551890'); # not really my password ;) + my ($pty, $pid) = $ssh->open2pty("ls /etc") + or die "open2pty failed: " . $ssh->error . "\n"; + + my $expect = Expect->init($pty); + $expect->raw_pty(1); + $expect->log_stdout(1); + while(<$pty>) { + print "$_" + }

Replies are listed 'Best First'.
Re: Is it possible to see what Net::OpenSSH is doing?
by salva (Abbot) on Jun 12, 2013 at 11:08 UTC
    Net::OpenSSH or actually the SSH protocol do not work exactly like that. There is not a remote session where you send commands and get the response back.

    Instead there is a binary protocol and on top of it bidirectional IO channels can be created and remote commands or port forwarders attached to them.

    In general there is no way to see the IO operations happening because there are handled directly by the master ssh program running on the background. The exception is when you use capturing methods as then, it is Net::OpenSSH who is talking at the other side.

    In any case, the module has a debugging mode. For instance, setting...

    $Net::OpenSSH::debug = 4|8|64;
    ... would give you a good idea of what is going on.

    Another possibility is to pipe the output of any command through tee so that it appears on the screen and is also saved to a file:

    $ssh->system({ stdout_file => ['|-', 'tee'. 'cmd_output.txt ], stderr_to_stdout => 1 }, @cmd);

      Hm, I was thinking with the ability to make an interactive shell with Expect, and then the ability to type/send commands and get/receive that command's output, maybe I could get that interactive shell and somehow have Net::OpenSSH type/send commands to the shell rather than me. I even tried setting master_stdout(stderr)_fh's to the pty device, but obviously that didn't work. I thought I was on to something a bit ago, but kept ending with the error 'Error: could not connect pty as controlling terminal'. Darn.

        Net::OpenSSH does not send commands to a shell.

        A possible way, quite difficult, may be to abuse the OSTracer interface that allows to run the master ssh process with strace (or your favourite OS equivalent).

        You will have to write your own tracer able to dump the IO interactions of the ssh master process to the console.

Re: Is it possible to see what Net::OpenSSH is doing?
by jonadab (Parson) on Jun 27, 2013 at 14:59 UTC

    One thing you can do, quite easily, is have your program print comments about what it's doing (right before calling $ssh->capture2() or whatever), and of course it can print any captured output or error string afterward, so your output can look something like this:

    Connecting to remotehost... Connected. Attempting to log in... Logged in. Sending command: cd /var/foo/wibble Command succeeded. No output. Sending command: cd - Command succeeded. Output: /home/jonadab Sending command: cd /directory-that-does-not-exist Command FAILED. Error information: cd: /directory-that-does-not-exist: No such file or directory

    If you want to get fancy, you could even use Term::ANSIColor and display different things in different colors (e.g., output in green, errors in bright magenta, comments in white, and commands in bright yellow, all on a black background; or whatever colors make you happy).

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1038427]
Approved by Corion
Discipulus what?! penitentiagite monaci!

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2018-06-21 20:24 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (119 votes). Check out past polls.