i Get IPv4 Addresses For Multiple Adaptors · Dark Matter Industries

Get IPv4 Addresses For Multiple Adaptors

I connect my MacBook Pro to an ancient 27” Apple Thunderbolt Display. It goes from MBP USB-C -> Apple USB-C to Thunderbolt 3 Adaptor -> Thunderbolt 3 Cable -> Display. (The built in cable is a little flaky after 8 years of daily use.)

My Thunderbolt Display is permanently connected to my network with an ethernet cable. This means that when I dock my MacBook Pro, I most usually have both a wired and wireless connection to my network.

So what is the most efficient way of getting both IP addresses?

You could use ipconfig:

% ipconfig getifaddr en0
192.168.1.144

but then you’d have to remember the names of the adaptors and do this for each one. You could script it but while my wired connection is mostly en0 the wireless one depends on a number of factors. So I cannot tell in advance whether it is en5 or en7 etc. Also, I always want a script to be portable so I can use it on other machines.

One solution is to use ifconfig and grep for “netmask” since a netmask is applied only when an IPv4 address is defined for an adaptor. And, as you will see below, I grab the results 5 lines above and 4 lines below the word “netmask” for information on the adaptor in question at a glance. Finally, I use the --color option in grep to make “netmask” pop. You can’t see it in the listing below because I can’t be bothered to figure out a way to turn off syntax highlighting and change the color of single words in markdown. If you are curious you should run it yourself.

% ifconfig | grep --color -A 5 -B 4 netmask
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
	inet 127.0.0.1 netmask 0xff000000 
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	nd6 options=201<PERFORMNUD,DAD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
--
--
en7: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=50b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV,CHANNEL_IO>
	ether c8:2a:14:4f:08:29 
	inet6 fe80::c42:84e9:d784:dfc7%en7 prefixlen 64 secured scopeid 0x4 
	inet 192.168.1.140 netmask 0xffffff00 broadcast 192.168.1.255
	inet6 fd00::1:1c32:2675:22ff:1ad0 prefixlen 64 autoconf secured 
	inet6 fd00::1:5566:2edb:d011:cebe prefixlen 64 deprecated autoconf temporary 
	inet6 fd00::1:f5f9:6a0e:c793:f18e prefixlen 64 autoconf temporary 
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect (1000baseT <full-duplex,flow-control>)
--
--
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=400<CHANNEL_IO>
	ether 88:e9:fe:6c:92:53 
	inet6 fe80::85a:3733:47db:c7b%en0 prefixlen 64 secured scopeid 0x6 
	inet 192.168.1.141 netmask 0xffffff00 broadcast 192.168.1.255
	inet6 fd00::1:10ee:3265:3681:a038 prefixlen 64 autoconf secured 
	inet6 fd00::1:f57a:ee3:adbe:be7c prefixlen 64 autoconf temporary 
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active

From the above I can tell at a glance the IP addresses of my active network adaptors.

But why stop there? That is a moderately long command to type (yes, you could use bash’s or zsh’s fantastic history and recall that command in potentially 3 keystrokes: CTRL-R, n, e) but I’m all for optimising everything without losing sight of Occam’s Razor. So I just create an alias in my .zshrc:

alias ip=ifconfig | grep --color -A -B 4 netmask

I love it for its simplicity, but of course, there is a more elegant way to do this. The following is a demonstration of how, as your nix-fu skills improve, your solutions get closer to what you envision them to be in the first place.

I discovered this script a few years ago, but I can’t remember where it came from. The shell script that goes through ifconfig, looks for the keyword inet and outputs the adaptor label and the next word that appears after inet, which is the IPv4 address. (All hail the mighty Awk…)

#!/bin/sh
for name in $(ifconfig -l)
do
	ifconfig $name | awk -v name=$name '/inet / { printf "%s: %s\n", name, $2; }'
done

Will produce this output:

% ./IP.sh 
lo0: 127.0.0.1
en7: 192.168.1.140
en0: 192.168.1.141