Printing network details

Hi ALL,

I am trying to collect and print all the network interface details in linux shell script.
operating system : centos 7

Below is my shell script :

#!/usr/bin/env bash
for i in $(ip link show | awk -F: '$1>0 {print $2}')


do

if [ $i == lo ]; then


echo -e "{\"'name'\":\"'"$i"'\",\"'ip_address'\":'"$(ifconfig $i |grep inet |grep -v inet6 |awk '{print $2}')"',\"'packet_max_size'\":'"$(ifconfig $i |grep mtu | awk '{print $NF}')"',\"'ip_subnet'\":'"$(ifconfig $i |grep inet |grep -v inet6 |awk '{print $4}')"',\"'dns_server'\":'"$(cat /etc/resolv.conf |grep -i '^nameserver'|head -n1|cut -d ' ' -f2)"',\"'received_packets'\":'"$(ifconfig $i |grep -i RX |head -1 |awk '{print $3}')"',\"'type'\":'"$(ls -lrt /sys/class/net/ |grep $i |awk ' {print $11}' |awk -F "/" ' {print $4}')"',\"'Flg'\":'"$(ifconfig -s $i |grep -v Flg |awk '{print $11}')"',\"'sent_packets'\":'"$(ifconfig $i |grep  TX |head -1 |awk '{print $3}')"'}"
fi
if [ $i != lo ]; then


echo -e "{\"'name'\":\"'"$i"'\",\"'ip_address'\":'"$(ifconfig $i |grep inet |grep -v inet6 |awk '{print $2}')"',\"'mac_address'\":'"$(ifconfig $i |grep ether |awk '{print $2}')"',\"'dhcp_enabled'\":'"$(cat  /etc/sysconfig/network-scripts/ifcfg-$i |grep BOOTPROTO |awk -F "=" '{print $2}')"',\"'packet_max_size'\":'"$(ifconfig $i |grep mtu | awk '{print $NF}')"',\"'speed'\":'"$(sudo ethtool $i |grep Speed |awk '{print $2}')"',\"'ip_subnet'\":'"$(ifconfig $i |grep inet |grep -v inet6 |awk '{print $4}')"',\"'dns_server'\":'"$(cat /etc/resolv.conf |grep -i '^nameserver'|head -n1|cut -d ' ' -f2)"',\"'received_packets'\":'"$(ifconfig $i |grep -i RX |head -1 |awk '{print $3}')"',\"'type'\":'"physical"',\"'Flg'\":'"$(ifconfig -s $i |grep -v Flg |awk '{print $11}')"',\"'sent_packets'\":'"$(ifconfig $i |grep  TX |head -1 |awk '{print $3}')"'}"


fi

done

Ouput :

{"'name'":"'lo'","'ip_address'":'127.0.0.1',"'packet_max_size'":'65536',"'ip_subnet'":'255.0.0.0',"'dns_server'":'8.8.8.8',"'received_packets'":'39651',"'type'":'virtual',"'Flg'":'LRU',"'sent_packets'":'39651'}
{"'name'":"'eno16780032'","'ip_address'":'192.168.20.120',"'mac_address'":'00:0c:29:df:1e:7a',"'dhcp_enabled'":'dhcp',"'packet_max_size'":'1500',"'speed'":'10000Mb/s',"'ip_subnet'":'255.255.255.0',"'dns_server'":'8.8.8.8',"'received_packets'":'55599',"'type'":'physical',"'Flg'":'BMRU',"'sent_packets'":'65397'}

I want to expand this shell script based on the flg variable ouput.

if flg variable ouput is LRU i want to add two more variables(description and status)
if flg variable ouput is BMRU i want to add two more variables(description and status)

Desired output :
if flg variable ouput is LRU

{"'name'":"'lo'","'status'":'up',"'ip_address'":'127.0.0.1',"'description'":'it is a loop back device',"'packet_max_size'":'65536',"'ip_subnet'":'255.0.0.0',"'dns_server'":'8.8.8.8',"'received_packets'":'39651',"'type'":'virtual',"'Flg'":'LRU',"'sent_packets'":'39651'}

if flg variable ouput is BMRU

{"'name'":"'eno16780032'","'status'":'up',"'description'":'it is a broadcast address supporting multicast',"'ip_address'":'127.0.0.1',"'ip_address'":'192.168.20.120',"'mac_address'":'00:0c:29:df:1e:7a',"'dhcp_enabled'":'dhcp',"'packet_max_size'":'1500',"'speed'":'10000Mb/s',"'ip_subnet'":'255.255.255.0',"'dns_server'":'8.8.8.8',"'received_packets'":'55599',"'type'":'physical',"'Flg'":'BMRU',"'sent_packets'":'65397'}

Can someone please help.

You may want to first disentangle this kludge of a script before you start to add functionality. I don't know your monitor but i am quite sure the echo -lines are not fitting onto it.On my terminal it spans ten lines and i refuse to read beyond the first.

How about:

#!/usr/bin/env bash



get_ipaddress ()
{
name="$1"
printf "%s\n" "$(ifconfig $name | grep  inet[^6] | awk '{print  $2}')"


return 0
}




get_packetmaxsize ()
{
name="$1"
print "%s\n" $(ifconfig $i |grep mtu | awk '{print  $NF}')


return 0
}





for i in $(ip link show | awk -F: '$1>0 {print $2}') ; do
      if [ $i == "lo" ]; then
           print "\"%s\":\"%s\"" "$i" $(get_ipaddress "$i")
           print "\"%s\":\"%s\"" "packet_max_size" $(get_packetmaxsize "$i")
           [....]
           printf "\n"

      else
            print "\"%s\":\"%s\"" "$i" $(get_ipaddress "$i")
           print "\"%s\":\"%s\"" "packet_max_size" $(get_packetmaxsize "$i")
            [....]
           printf "\n"


     fi
done

Basically you create a single function for every information part you want, then put it all together in a main loop which cycles through all the interfaces. The creation of the other function is left to the interested reader as an exercise. This presents you the added opportunity to remove the UUOCs you so generously spilled into your code.

1 Like

Here is an awk example with ip -o option (among others).
Not everything is parsed, but you get the idea with this example how to proceed if you want (or not :slight_smile:

Perhaps somebody can shorten this out, assumption is ip with those options will print out stuff equally on linux boxes (for now probably :slight_smile: )
Correction and/or suggestions are welcomed of course!

Save following as intinfo.awk :

BEGIN {
FS="\\"
OFS=" "
}
{
# split first field on ":" into array a
split($1,a,":")
# hardcode wanted info from array members into variables
interface=a[2]
interface_info=a[3]
# split variable 'interface_info'  on "<space>" into array b
split(interface_info,b," ")
# iterate over array 'b' detecting info
for ( i in b ) {
	# if string state is matched
	if ( b == "state" )
	# define 'status' variable as next member of array
	status=b[i+1]
	# if string mtu is matched
	if ( b == "mtu" )
	# define 'mtu' variable as next member of array
	mtu=b[i+1]
}
# execute ethtool for information
ethtool="ethtool "interface
# while we read ethtool command output line by line
while ( ( ethtool | getline info ) > 0 ) {
# Detect speed and link status for interface
if ( match (info, /Speed: [0-9].*s/) )
	rmstr="Speed: "
     	speed=substr(info,RSTART+length(rmstr),RLENGTH)

( info ~ "Link detected: yes" )  ? lst="UP" : lst="DOWN"
}
close(ethtool)
# remove starting whitespace from interface name
gsub("^ ","",interface)
# print and output and json-ify whatever...
printf ("{\"'name'\":\"'%s'\",\"'status'\":'%s',\"'packet_max_size'\":'%s'}\n", interface, lst, mtu)

}

Ran on my home box :

root@glitch:~# ip -o -s -a l show  | awk -f intinfo.awk 
{"'name'":"'lo'","'status'":'UP',"'packet_max_size'":'65536'}
{"'name'":"'enp3s0'","'status'":'UP',"'packet_max_size'":'1500'}
{"'name'":"'ovs-system'","'status'":'DOWN',"'packet_max_size'":'1500'}
{"'name'":"'brclust'","'status'":'UP',"'packet_max_size'":'1500'}
{"'name'":"'brintlan'","'status'":'UP',"'packet_max_size'":'1500'}
{"'name'":"'brpub'","'status'":'UP',"'packet_max_size'":'1500'}
{"'name'":"'homelan0'","'status'":'UP',"'packet_max_size'":'1500'}
{"'name'":"'brvxlan'","'status'":'UP',"'packet_max_size'":'1500'}
{"'name'":"'vxlan_sys_4789'","'status'":'UP',"'packet_max_size'":'65000'}
{"'name'":"'vnet0'","'status'":'UP',"'packet_max_size'":'1500'}
{"'name'":"'vnet1'","'status'":'UP',"'packet_max_size'":'1500'}
{"'name'":"'vnet2'","'status'":'DOWN',"'packet_max_size'":'1500'}

Hope that helps
Regards
Peasant.