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

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.
  • Comment on Re^3: Losing my mind with Net::OpenSSH and Expect

Replies are listed 'Best First'.
Re^4: Losing my mind with Net::OpenSSH and Expect
by salva (Canon) on Mar 01, 2011 at 09:37 UTC

    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.
        I don't really want the program to die

        Well, you can catch die's wrapping them inside and eval block. Or you can handle errors in a different way, for instance, using the return value from the expect method:

        my $r = $expect->expect(2, [ qr/configtest:/ => sub { shift->send("$pass2 +\n"); exp_continue;} ], [ qr/Sorry/ => sub { print "Login failed +\n" } ], [ qr/.*#\s+/ => sub { print shift->match +}] ); if (!defined $r) { print "Timeout!\n"; } elsif ($r == 3) { $expect->interact(); } else { print "Login failed!\n"; }
        Regarding the error you get:
        Variable "$expect" is not imported at ./test.pl line 28. (Did you mean &expect instead?)
        You have some error in your script but without seeing the source code it is difficult to say what! You are probably not declaring the variable $expect in the right scope.