2

On a RHEL 7 box whose local IP address is 10.0.0.159, the following command prints out the IP 10.0.0.159:

$ echo "$(ifconfig eth0 | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | \
   grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')""(rw,sync)" 

What would the command have to change to in order to print out `10.0.0.0/8" instead?

slm
  • 363,520
  • 117
  • 767
  • 871
CodeMed
  • 5,079
  • 45
  • 100
  • 147

2 Answers2

3

NOTE: ifconfig is a deprecated cmd. your should be using cmds. in the iproute2 package going forward. Below I show how to use ip to accomplish what you want using the replacement tool.


Rather than do this with ifconfig I'd recommend using the ip command instead.

IP CIDR

This form shows the IP address in CIDR notation:

$ ip addr list eth0 | awk '/inet.*brd/ {print $2}'
10.0.2.15/24

-or-

$ ip a l eth0 | awk '/inet.*brd/ {print $2}'
10.0.2.15/24

Network CIDR

This form shows the network address in CIDR notation:

$ ip route show | awk '/eth0.*scope/ {print $1}'
10.0.2.0/24

ipcalc

You can also use the ipcalc command to manipulate the above addresses to calculate other formats. For example:

$ ipcalc -n $(ip a l eth0 | awk '/inet.*brd/ {print $2}')
NETWORK=10.0.2.0

$ ipcalc -p $(ip a l eth0 | awk '/inet.*brd/ {print $2}')
PREFIX=24

With ipcalc you can use it to more simply form whatever variations you want, rather than have to do a lot of sed & awk to parse text that's typically overly complicated to do.

slm
  • 363,520
  • 117
  • 767
  • 871
3

To change a command line to do what you want, first you need to understand what it is doing. Here's an analysis:

echo "$(<something>)""(rw,sync)" 

Will run something and take it as input to your echo. Everything else is normal text to be echo'ed.

ifconfig eth0

Gets the network information.

grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' 

Isolates the several IPs in your system. -E tells grep to use regular expressions, which is why you can use [0-9]* to match all numbers together, for example. -o tells grep to output only the part that matches the regular expression, as opposed to outputting the whole line that matches the grep condition, as it would by default. So if for example the input line is inet addr:10.0.0.159 Bcast:10.0.0.255 Mask:255.255.255.0, it will only output inet addr:10.0.0.159 leaving out the Bcast and Mask parts.

grep -Eo  '([0-9]*\.){3}[0-9]*' 

This is exactly the same as above, except without the label inet addr, meaning you're isolating specifically the IP and removing the label. And finally,

grep -v '127.0.0.1'

is removing that one IP from your list of outputs, because you don't care about the loopback IP.


As you can see, your command is getting the output of ifconfig and filtering information out, isolating only the piece of information that you want. It's not doing any calculations or information processing. But what you want it to print is the subnet and mask, which are information that are not explicitly displayed by ifconfig. In other words you can't just filter things out differently to get what you want. You will have to do some processing, some calculation using the Mask field at the end of the line. In summary, you can't "change the command to print out what you want". You have to create a completely different command.

slm's answer uses a similar technique (filtering out information to keep only what you want), but changed the input to a command that will have the information that you need. :-) If you didn't have a command that outputs exactly what you want, and doing some processing on it was your only option, here's an ugly set of ifs that you can use as an example or base in the future. It uses slm's first solution, and it assumes your mask is always 8, 16 or 24.

ip a l eth1 | awk '/inet.*brd/ {split($2,add,"/");split(add[1],ip,".");if(add[2]<=24){ip[4]=0} if(add[2]<=16){ip[3]=0} if(add[2]<=8){ip[2]=0} print ip[1]"."ip[2]"."ip[3]"."ip[4]"/"add[2];}'

This command split the output of ip between address (10.0.0.159) and mask (8). Then it splits the IP into its 4 numbers. Then it sets the numbers to zero according to the mask. But it's not bitwise, meaning it will only deal with masks 8, 16 and 24, because that's what I hardcoded. ;)

I hope you could learn a bit more about the tools at your hand. ^_^

msb
  • 2,554
  • 2
  • 13
  • 11