Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extracting an IP address to a variable using Expect script

Hi I am new to Expect scripting, and I have been trying to fetch an IP address into a variable using following :

set timeout -1
spawn $env(SHELL)
match_max 100000
send "ifconfig | grep -A 1 'eth1' | tail -1\r "
expect -re "inet addr:.* " {send "ping $expect_out(0,string)\r"}
send -- "exit\r"
expect eof

The problem is that it is trying to ping with the result of the ifconfig command which has some string characters in it.

Could anyone help me to extract just IP address from the ifconfig command and store it in a variable? I have been using $expect_out(buffer) as well, but just couldn't get my head around it. Any help along these lines would be much appreciated.

like image 737
Mmudalagiri Avatar asked May 12 '26 09:05

Mmudalagiri


2 Answers

You don't need to spawn a shell:

spawn ifconfig eth1
expect -re {inet addr:(\S+)}
set ipaddr $expect_out(1,string)
expect eof

spawn ping -c 10 $ipaddr
expect eof

In fact, you don't need to use Expect: in plain Tcl (with extra error checking for ping):

if {[regexp {inet addr:(\S+)} [exec ifconfig eth1] -> ipaddr]} {
    set status [catch [list exec ping -c 10 $ipaddr] output]
    if {$status == 0} {
        puts "no errors from ping: $output"
    } else {
        puts "ERROR: $output"
    }
}
like image 115
glenn jackman Avatar answered May 14 '26 13:05

glenn jackman


You could use regexp on your existing code:

expect -re "inet addr:.* " {
  regexp {inet.*?(\d+\.\d+\.\d+\.\d+)} $expect_out(buffer) match ip
  puts "Pinging $ip"
  send "ping $ip\r"
}

In the line:

regexp {inet.*?(\d+\.\d+\.\d+\.\d+)} $expect_out(buffer) match ip

The regexp command is capturing the ip address in a bracketed 'capture group':

(\d+\.\d+\.\d+\.\d+)

And then storing it in the variable ip.

The expect_out(buffer) variable is the source string containing everything read so far by expect (up to your expect -re command), and match is another variable which stores a string that matches the entire regex (everything from 'inet' to the end of the ip address.) match is simply there to conform to the regexp syntax of requiring a variable to be present before the capture groups- it's throwaway data in this particular example- a reworked version of regexp could use match to store the ip for this example, but in general I find capture groups more flexible, as you can have several to catch different pieces of data from a single string.

You may want to read up on the regexp command and, regular expressions in general, as Expect makes quite extensive use of them.

like image 31
Niall Byrne Avatar answered May 14 '26 14:05

Niall Byrne



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!