Mmudalagiri
Mmudalagiri

Reputation: 31

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.

Upvotes: 3

Views: 5873

Answers (4)

amar
amar

Reputation: 499

$ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:1b:fc:72:84:12  
      inet addr:172.16.1.13  Bcast:172.16.1.255  Mask:255.255.255.0
      inet6 addr: fe80::21b:fcff:fe72:8412/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:638661 errors:0 dropped:20 overruns:0 frame:0
      TX packets:93858 errors:0 dropped:0 overruns:0 carrier:2
      collisions:0 txqueuelen:1000 
      RX bytes:101655955 (101.6 MB)  TX bytes:42802760 (42.8 MB)
      Memory:dffc0000-e0000000 

lo        Link encap:Local Loopback  
      inet addr:127.0.0.1  Mask:255.0.0.0
      inet6 addr: ::1/128 Scope:Host
      UP LOOPBACK RUNNING  MTU:16436  Metric:1
      RX packets:3796 errors:0 dropped:0 overruns:0 frame:0
      TX packets:3796 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:517624 (517.6 KB)  TX bytes:517624 (517.6 KB)

try this:

ifconfig | sed '2,2!d' | sed 's/.*addr://' | sed 's/\ .*//' > ipaddress

this will give ip

$vi ipaddress 

Upvotes: 0

Niall Byrne
Niall Byrne

Reputation: 2460

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.

Upvotes: 1

glenn jackman
glenn jackman

Reputation: 247062

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"
    }
}

Upvotes: 4

Lipongo
Lipongo

Reputation: 1259

Change your 'send "ifconfig | grep -A 1 'en1' | tail -1\r" to look like the below line instead.

send "ifconfig | grep -A 1 'en1' | tail -1 | cut -d' ' -f2\r"

Upvotes: 0

Related Questions