Extracting an IP address to a variable using Expect script - expect

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.

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

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.

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"

$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

Related

Does anybody know what is the reason that question mark matches nothing in ubuntu 19.10?

When i use a dot(.) in globbing pattern, it successfully matches this bunch of addresses:
~$ ip addr show | grep i.et
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
inet 192.168.1.101/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp3s0
inet6 fe80::c705:4836:6aa7:d321/64 scope link noprefixroutet
At the same time, the question-marked version matches nothing:
~$ ip addr show | grep i?et
Any ideas?
Grep's patterns are regular expressions. The question mark you are trying to use is part of Bash's globbing (pattern matching).
Example using globbing:
ls -1d /proc/191?
returns :
/proc/1910
/proc/1913
/proc/1914
/proc/1915
/proc/1916
/proc/1918
/proc/1919
Now with grep's regular expressions (regex):
ls -1 /proc | grep '191.'
returns:
1910
1913
1914
1915
1916
1918
1919
Hope that helps clear up the confusion.

bash how to extract iface inet and mask from ifconfig

Can anyone help filter the information from ipconfig
the information im getting is
enp37s0 Link encap:Ethernet HWaddr 2c:41:38:15:41:30
inet addr:192.168.0.105 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::89be:e3f9:b746:19ed/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4593332 errors:0 dropped:0 overruns:0 frame:0
TX packets:2313662 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:6506620971 (6.5 GB) TX bytes:182579364 (182.5 MB)
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:65536 Metric:1
RX packets:9574 errors:0 dropped:0 overruns:0 frame:0
TX packets:9574 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1100854 (1.1 MB) TX bytes:1100854 (1.1 MB)
wlo1 Link encap:Ethernet HWaddr d0:df:9a:6c:7c:1d
inet addr:192.168.0.103 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::225d:a288:5fa7:2237/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:124147 errors:0 dropped:0 overruns:0 frame:0
TX packets:2681 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:32988267 (32.9 MB) TX bytes:266523 (266.5 KB)
And i would like to get.
enp37s0 : 192.168.0.105/255.255.255.0
lo : 127.0.0.1/255.0.0.0
wlo1: 192.168.0.103/255.255.255.0
The syntax will change depending on what operating system you're using, but you can use some sed commands to get the output you want. For example the command on my Arch Linux system is ifconfig (f not p) and my output is formatted a little differently. But here's something that ought to work on your system:
ipconfig | tr '\n' '~' | sed 's/~~/\n/g' | sed 's/~/ /g' | sed -E 's/^\s*(\S+)\s+.*\s+inet\s+(\S+)\s.*$/\1 \2/g'
We do a few things here:
Replace all the newlines with some unused character, here ~, because your interface name (enp37s0) and IP address (192.168.0.105) are on different lines, and we need to merge them onto the same line
Replace ~~ (which would have been two consecutive newlines - the separator between interfaces) with a single newline. This will effectively make sed operate on each interface separately in the remaining steps
Replace ~ (which would have been a single newline) with a space; this ensures we don't inadvertently join any parts of the original output (for example, we might get 30inet from the first two lines being joined together, but we want 30 inet since we're looking for inet
Finally the main part, we extract the first word on each line, then we look for the inet word and also extract the word immediately after it on that same line. We also discard everything after the first word and before inet, and everything after the word after inet. Here a "word" means anything separated by whitespace. \s in a regex matches whitespace and \S matches anything that isn't whitespace, so ^\s*(\S+)\s+ finds our first word, .* gets rid of anything following it, \s+inet\s+(\S+)\s finds inet and the word after it, and .*$ gets rid of anything to the end of the line.
This will produce the following in your case:
enp37s0 addr:192.168.0.105
lo addr:127.0.0.1
wlo1 addr:192.168.0.103
If you want to see what each individual step does, you can of course just execute part of the command.
Removing the addr: and/or adding the Mask into the result is left as an exercise to the reader as similar techniques can be used.
Challenge accepted :-)
Try this one-liner:
for ip in $(hostname -I | grep -Eo '([0-9]*\.){3}[0-9]*'); do echo ""$(ifconfig | grep -B1 "inet addr:"$ip | cut -d " " -f1 | tr -d " ")" : "$ip"/"$(ifconfig | grep "inet addr:"$ip | grep -Eo 'Mask:?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*') ; done;
Produces something like this on my Debian:
wlan1 : 192.168.1.116/255.255.255.0
docker_gwbridge : 172.18.0.1/255.255.0.0
br-2c830dcde04d : 172.25.0.1/255.255.0.0
br-d6bc6df716ef : 172.21.0.1/255.255.0.0
br-d6fccd14dfad : 172.19.0.1/255.255.0.0
br-df4c2b24c7c0 : 172.24.0.1/255.255.0.0
docker0 : 172.17.0.1/255.255.0.0
br-ef0e82befd79 : 172.22.0.1/255.255.0.0
br-fad2fced45f8 : 172.20.0.1/255.255.0.0
Some details if you're interested:
for ip in $(hostname -I | grep -Eo '([0-9]*\.){3}[0-9]*'); do
loop over IPv4 addresses in hostname output
ifconfig | grep -B1 "inet addr:"$ip | cut -d " " -f1 | tr -d " ")
take a matching line and the one above in ifconfig, then take the first word of that line above the IP address ... which should be the name of the interface
ifconfig | grep "inet addr:"$ip | grep -Eo 'Mask:?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*')
take that matching line again and search for a token with "Mask:", then extract the mask
Ok, I know, it is not pure bash, might not work on all OS variants, not even pure sed/grep on ifconfig, but... was fun to code it!

Putting a string on same line tcl

I have a nmap output and I need to put strings on different lines on same line.
Nmap Output:
Nmap scan report for 169.254.0.1
Host is up (0.014s latency).
Not shown: 97 closed ports
PORT STATE SERVICE
80/tcp open http
1720/tcp open H.323/Q.931
5060/tcp open sip
Device type: VoIP adapter|WAP|PBX|webcam|printer
New Ouput:
169.254.0.1,Voip adapter
How can I do this on tcl or bash?
In Tcl, we can use regexp to extract the required data.
set nmap_output "Nmap scan report for 169.254.0.1
Host is up (0.014s latency).
Not shown: 97 closed ports
PORT STATE SERVICE
80/tcp open http
1720/tcp open H.323/Q.931
5060/tcp open sip
Device type: VoIP adapter|WAP|PBX|webcam|printer"
if {[regexp {scan\s+report\s+for\s+(\S+).*Device\s+type:\s+([^|]+)} $nmap_output match ip type]} {
puts $ip,$type
}
Brute force:
<your_nmap_output> | \
egrep "Nmap scan report|Device type" | \
sed -r 's/[ ]*Nmap scan report for (.*)$/\1,/' | \
sed -r 's/[ ]*Device type: ([^\|]*)\|.*/\1/' | \
xargs

Calculate broadcast ip address using ipcalc

I have a list of ip addresses in cidr formart in a text file,one cidr per line and I would like to calculate the broadcast ip address of the cidr. I understand that I can do that using ipcalc with the -b option but ipcalc doesn't take a text file full of cidr. So, how to write a bash script to wrap around the ipcal command.
Here's a quick script that should do the trick:
Example file ips.txt
$ cat ips.txt
192.168.0.1/24
192.167.0.1/24
Example output for the ips in this file:
$ for i in $(cat ips.txt);do echo $i; ipcalc -b $i;done
192.168.0.1/24
BROADCAST=192.168.0.255
192.167.0.1/24
BROADCAST=192.167.0.255
If you don't need to output the ip address itself, just remove the echo.
Edit
Here's a version that prints only the broadcast address, as requested:
$ for i in $(cat ips.txt);do bcaddr=$(ipcalc -b $i);echo ${bcaddr#BROADCAST=};done
192.168.0.255
192.167.0.255

Bash - How to know my Linux server IP adress? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
Is there a way to echo only the server ip adress from Bash? I am on a Linux/Debian6.
My intent is to write to "/etc/hosts" the pair domain_name IP for each new domain I register in the server.
As this bash script will be opened for public use, I am trying to find a way of getting this information via cli.
CONCLUSION:
This is the final code, based on the clues my friends helped me with:
newhost() {
DMN=$1
X=`ifconfig | grep Bcast`
Y=`echo "${X#*:}"`
DNS=`echo "${Y%\ B*}"` # server DNS(207.112.37.222)
H='/etc/hosts' #hostfile
PAIR="$DNS\t$DMN"
if grep -i --silent "$DMN" "$H"; then
echo -e "$DMN already exists in $H"
else
bash <<EOF
echo -e "$PAIR" >> "$H"
EOF
echo -e "$PAIR added to $H"
fi
}
By the way, Isn't it funny that some born-already-smart dudes voted to close the question?
Thanks.
use:
ifconfig - your ip will be after the inet addr: in this case 1.1.1.1
sample output:
root#server [~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0A:E4:89:0B:97
inet addr:1.1.1.1 Bcast:1.1.1.63 Mask:255.255.255.192
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1/or modify
RX packets:14804377317 errors:0 dropped:0 overruns:0 frame:0
TX packets:11766937374 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:13799286299902 (12.5 TiB) TX bytes:4891709752100 (4.4 TiB)
Interrupt:169 Memory:fa000000-fa012800 will be useful,
http://www.debianadmin.com/network-interface-configuration-using-ifconfig.html
ip -4 a l dev $DEVICE | grep inet | awk '{ print $2 }'
replace $DEVICE with the device name. eth0 should be the right in the most cases

Resources