Search code examples
tclexpect

Identifying an IP in an Expect Script


I'm trying to get my expect script to recognize an IP address using regex. As far as I can tell, i can't get any regex strings to work.

Here's a snip of my code:

send "show router arp mac $MACADDR\r"
expect -re "^.\d+\.\d+\.\d+\.\d+.$"
    puts "Carrying on....."
    set IP_OUTPUT $expect_out(buffer) 
    puts $IP_OUTPUT
    puts "Yay! That was success!!"
}

I've tried numerous styles of regex, but they all seem to give about the same results.....none.

The command is executed as expected and is returning the information needed, but the expect gets the next line, (the prompt for a new command)

What I expect $IP_OUTPUT to look like

A::device.name# show router arp mac 00:00:00:00:00:00

===============================================================================
ARP Table (Router: Base)
===============================================================================
IP Address      MAC Address       Expiry    Type   Interface
-------------------------------------------------------------------------------
10.0.0.2    00:00:00:00:00:00 03h53m17s Dyn[I] Vlan799
===============================================================================

But all its giving me is 'A:device.name# '


Solution

  • Strings between double-quotes are going through a round of substitution before being handed to the command. So, you are asking for the output to exactly match four sequences of one or more d's, with any character in between and on either side, because the regexp passed to the expect command will be "^.d+.d+.d+.d+.$".

    First of all, you should put your pattern inside curly braces to prevent this round of substitution. Second, you almost never want to anchor patterns when using expect. Finally, I don't think you want a character on either side of the IP address.

    This may be more like you want:

    send "show router arp mac $MACADDR\r"
    expect -re {\d+\.\d+\.\d+\.\d+} {
        puts "Carrying on....."
        set IP_OUTPUT $expect_out(buffer) 
        puts $IP_OUTPUT
        puts "Yay! That was success!!"
    }
    

    If you actually want to get the output you showed, you need a pattern that matches all the way up to the end of the report, because otherwise expect may stop prematurely. In that case you may have to use something like:

    expect -re {.*\d+\.\d+\.\d+\.\d+.*=\n}