Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Expect problems

by sunadmn (Curate)
on Dec 15, 2005 at 22:14 UTC ( #517090=perlquestion: print w/replies, xml ) Need Help??

sunadmn has asked for the wisdom of the Perl Monks concerning the following question:

Hey all I have this really simple expect script I am writing to log into a L4 switch and switch a server into or out of production and for some reason after I send the first command to the session my next regex doesn't match. Here is the code I have thus far:

This is the expected second prompt:

>> Real server 144 -

#!/usr/bin/perl -w # Script using Expect to roll servers in PHX in # the pop in and out of the VIP use strict; use warnings; use Expect; # Setup our reusable varibles here ( host password etc ) my $telnet = '/bin/telnet'; my $host = ""; my $passwd = "mypass"; my $timeout = '10'; my $infocmd = '/info/slb/dump'; my $rcmd = '/cfg/slb/real'; my $apply = 'apply'; my $save = 'save'; my $yes = 'y'; my $no = 'n'; my $exit = 'exit'; my $serverL = '/var/tmp/server_list_vip'; # interact a bit till I get the CGI wrapper figured out print "Welcome to the PHX vip roll-in/out script\n I will show you a list of servers you can roll in and out of th +e vip\n choose the correct number for the given server\n EXAMPLE: If you want to roll newsfe01 in/out in the list you wi +ll see\n 144: newsfe01, so the correct number is 144\n"; open(IN,"$serverL"); chomp(my @list = <IN>); close(IN); foreach my $line(@list) { print "$line\n"; } print "Choose the server number now:\n"; chomp(my $number = <STDIN>); print "What action do you want to take?\n Roll server into production = ena\n Roll server out of production = dis\n"; chomp(my $action = <STDIN>); my $exp = Expect->spawn("$telnet $host") or die "Cannot spawn telnet to $host: $!\n";; my $spawn_ok; if($action =~ m/dis/) { my $func = 'dis'; $exp->expect($timeout, [qr'Enter password: $', sub{ $spawn_ok = 1; my $fh = shift; print $fh "$passwd\r"; #$fh->send("$passwd\n"); exp_continue;} ], [qr'>> Main- $', sub{ $spawn_ok = 1; my $fh = shift; print $fh "$rcmd $number/$func\r"; sleep 2; exp_continue; }],
This is where the interactions fails at
[qr'>> Real server $number - $', sub{ $spawn_ok = 1; my $fh = shift; print $fh "$apply\r"; sleep 2; exp_continue; }], [qr'>> Real server $number - $', sub{ $spawn_ok = 1; my $fh = shift; print $fh "$save\r"; sleep 2; exp_continue; }], [qr'Confirm saving to FLASH [y/n]: $', sub{ $spawn_ok = 1; my $fh = shift; print $fh "$yes\r"; sleep 2; exp_continue; }], [qr'>> Real server $number - $', sub{ $spawn_ok = 1; my $fh = shift; print $fh "$exit\r"; exp_continue; }] ); }

If anyone has a clue here please share as I am pretty lost at this point.

Thanks all

Replies are listed 'Best First'.
Re: Expect problems
by tirwhan (Abbot) on Dec 15, 2005 at 22:48 UTC

    If you're unsure whether either your script or the remote server are saying what you think they should be saying, you could set up a proxy and watch the network transaction as it takes place. A very handy tool for that is socat, execute:

    socat -v tcp4-listen:4242

    and point your script at port 4242 on your local host. This should show you what is going on.

    Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
Re: Expect problems
by GrandFather (Sage) on Dec 15, 2005 at 22:54 UTC

    Are you sure there is a trailing space in '>> Real server 144 - ' and that there are no extra characters (perhaps a cr character?)?

    DWIM is Perl's answer to Gödel
      Ok so like I stated in my last post I have it working but for some reason I get it to get beyond the apply stage due to the fact that the next prompt looks the same. Below is a copy of the session when I do this manually:

      >> Main- /cfg/slb/real 144/ena
      Current status: disabled
      New status: enabled

      >> Real server 144 - apply
      Apply complete; don't forget to "save" updated

      >> Real server 144 - save
      Request will first copy the FLASH "active" config to "backup",
      then overlay FLASH "active" with new config.
      Confirm saving to FLASH y/n: y
      New config successfully saved to FLASH.

      >> Real server 144 - exit

      So as you can see after the apply at the >> Real server 144 - prompt next I should/want to send "save" but expect get's stuck on the "apply" and wont move on to the next case match so it's almost like the thing goes into a never ending loop. Does anyone know of a way to force it to move on??

      USE PERL
Re: Expect problems
by GrandFather (Sage) on Dec 15, 2005 at 22:21 UTC

    I can't be bothered reading all that code. But if you show us the text you expect to match and the regex you expect to match it I bet you'll get a quick answer - or maybe even see the problem for yourself! (see I know what I mean. Why don't you?)

    DWIM is Perl's answer to Gödel
Re: Expect problems
by runrig (Abbot) on Dec 15, 2005 at 23:38 UTC
    use exp_internal to debug the interaction between command output and what you are expecting to match.
      Would you happen to have an example of the correct syntax for using that?? The perldoc has my head spinning at this point.

      Thanks a Million
      USE PERL
        This is straight from the docs:
        $object->exp_internal(0 | 1)
        You call the exp_internal method on the expect object with an argument of zero or one.
Re: Expect problems
by merlyn (Sage) on Dec 16, 2005 at 00:57 UTC
Re: Expect problems
by sunadmn (Curate) on Dec 16, 2005 at 04:57 UTC
    Ok so I did some further debuging and I have things working till the next case match:

    [qr">> Real server $number - $", sub{ $spawn_ok = 1; my $fh = shift; print $fh "$apply\r"; sleep 2; exp_continue; }],
    When I see the next >> Real server I am stuck in the apply loop and it wont send the save command, so I wondered if I could do a double match like look for the line before and then match the >> Real server line for the save command
    [qr">> Real server $number - $", sub{ $spawn_ok = 1; my $fh = shift; print $fh "$save\r";
    Does anyone have any thoughts on this??

    Thanks all
      In the original code you were looking for the same pattern twice. You were probably thinking that the first time expect sees the prompt it would match the first case and that second time expect sees the prompt it would match the second case.

      This would not work. You need to, within one case, check to see how many times you have seen that prompt. Zero times? do your Apply. Seen it once before? do your save. Seen it twice before? do whatever you need to do next.

      In other words keep a counter of how many times you have come across that prompt and send the appropriate response.


        This probably going to sounds like a stupid question, but would you have a suggestion on how to keep the counter for the case matches??

        Thanks a million
        USE PERL

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://517090]
Approved by GrandFather
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2020-05-27 10:34 GMT
Find Nodes?
    Voting Booth?
    If programming languages were movie genres, Perl would be:

    Results (154 votes). Check out past polls.