2

I am using Expect module in Perl to do an interactive activity and execute a command on a remote machine. Request your help on this

Here are the steps I used

Do a switch user to another account. Sends the password to login. Once I get the shell for the new user, execute a ssh command to connect to a remote machine.

Then I want to execute a command in that remote machine and get its response. I am able to execute the command on the remote machine. I am seeing the output on my terminal too. But I am not able to capture it in a variable so that I can compare it against a value.

use Expect;   
my $exp = Expect->new;
$exp->raw_pty(1);

$exp->spawn('su - crazy_user') or die "Cannot spawn switch user cmd: $!\n"
$exp->expect($timeout,
  [ qr/Password:/i,
            sub {   my $self = shift;
                    $self->send("$passwd\n");
                    exp_continue;
     }],

  [ qr/\-bash\-4.1\$/i,
            sub {   my $self = shift;
                    $self->send("ssh $REMOTE_MACHINE\n");
        $self->send("$COMMAND1\n");
        exp_continue;
  }]
 );
 $exp->soft_close();

How can I get the result of the $COMMAND1 that I executed on the remote machine via $self->send("$COMMAND1\n") ?

pynexj
  • 19,215
  • 5
  • 38
  • 56
Joseph
  • 41
  • 4

1 Answers1

1

I am by no means an expert on this but as noone else has answered so far, let me attempt it.

Your expect command is the su and as such, normal expecting will only work on whatever that command answers back to your original shell. That however is only the password prompt and maybe some error messages. You can still send commands, but their responses show up on the shell of the new user, not the shell the expect command has been executed in. That is why they show up on screen but not in the stream available to your expect object. Note that you would likely encounter the very same problem if you where to ssh directly (i am not sure why you would su and then ssh anyways, could you not directly ssh crazy-user@remote_machine?).

The solution is probably to get rid of the su and ssh directly into the user you need on the remote machine employing Net::SSH::Expect instead of plain Expect as it gives you everything written to the remote console in its output stream. But be careful, if i remember correctly, the syntax for inspecting the stream is slightly different.

DeVadder
  • 1,404
  • 10
  • 18
  • Thank you @DeVadder for the response. Earlier I was doing it in a complicated way. Now I did a direct ssh and executed the command and I am able to achieve whatever I wanted. my $result = ssh crazy-user@RemoteServer "COMMAND1". Then I parsed $result to do the rest of the operation – Joseph Nov 18 '14 at 07:51
  • @Joseph Ah well, yes, that is probably the best way as long as COMMAND only gives you something in return and is not interactive. – DeVadder Nov 18 '14 at 13:39