in reply to Re: Losing my mind with Net::OpenSSH and Expect
in thread Losing my mind with Net::OpenSSH and Expect

Hi Salva,

Thanks for the response. When I did it just as you said, I got:

fcntl returned undef during exp_init of Expect=GLOB(0x97b1760), Bad fi +le descriptor
I had had issues trying to include the -k in the sudo command, so I made it a separate $ssh->system() call, and it does seem to work except that I have to hit Enter for it to go into interactive mode. Sounds trivial, I know, but I'm hitting rather a lot of machines.

If I get rid of exp_continue after sending the password, it goes straightaway. Unfortunately, if it fails it doesn't catch the "Sorry", and just prompts me for a password. So it's a catch-22.

I'll be darned if I can detect a substantive difference between your code and mine, too, beyond what I've mentioned!

I'm on Ubuntu 10 and OpenSSH:
OpenSSH_5.5p1 Debian-4ubuntu5, OpenSSL 0.9.8o 01 Jun 2010

Replies are listed 'Best First'.
Re^3: Losing my mind with Net::OpenSSH and Expect
by rastoboy (Monk) on Mar 01, 2011 at 00:58 UTC
    For clarity, when I moved the -k out of the open2pty call, I got rid of the new error message. So it's interesting that you didn't have that issue.

      I had had issues trying to include the -k in the sudo command

      The -k switch may be a recent addition to sudo not yet available in the version you have installed.

      and it does seem to work except that I have to hit Enter for it to go into interactive mode

      You are already in interactive mode but you don't notice it because Expect is eating the shell prompt. Try the following script:

      #!/usr/bin/perl use strict; use warnings; use Net::OpenSSH; use Expect; my $host = $ARGV[0]; my $pass1 = $ARGV[1]; my $pass2 = $ARGV[2]; my $ssh = Net::OpenSSH->new($host, passwd => $pass1); $ssh->error and die "unable to connect to remote host: " . $ssh->error +; $ssh->system("sudo -K"); my ( $pty, $pid ) = $ssh->open2pty({stderr_to_stdout => 1}, 'sudo', -p + => 'configtest:', 'bash', '-i') or return "failed to attempt sudo bash: $!\n"; my $expect = Expect->init($pty); $expect->expect(2, [ qr/configtest:/ => sub { shift->send("$pass2\n"); ex +p_continue;} ], [ qr/Sorry/ => sub { die "Login failed" } ], [ qr/.*#\s+/ => sub { print shift->match }] ) or die "Timeout!"; $expect->interact();
        Man that's really weird. Success works pretty good, but failing gracefully is still my bugaboo. I still get the "Sorry" prompt, unless I change the key from a regex to a string match. And even then, if I don't have an actual "die" in the subroutine (that dies as it should), I still get the prompt. I don't really want the program to die, I just want to sever the connection and move on to the next machine, for example.

        It makes me wonder if it isn't coming up in some other sort of context or something. I tried adding multiline and global match commands after the regex but Expect didn't like that at all:

        Variable "$expect" is not imported at ./test.pl line 28. (Did you mean &expect instead?)
        Very weird.