Get network interface name and MAC address on command line

If you're on Ubuntu, you can get the MAC address from /sys/class/net/<dev>/address:

$ cat /sys/class/net/enp0s3/address
08:00:27:15:dc:fd

So, something like:

find /sys/class/net -mindepth 1 -maxdepth 1 ! -name lo -printf "%P: " -execdir cat {}/address \;

Gives me:

enp0s3: 08:00:27:15:dc:fd
docker0: 02:42:61:cb:85:33

Or, using ip's one-line mode, which is convenient for scripting:

$ ip -o link | awk '$2 != "lo:" {print $2, $(NF-2)}'
enp0s3: 08:00:27:15:dc:fd
docker0: 02:42:61:cb:85:33

Using ip link

ip -o link | grep ether | awk '{ print $2" : "$17 }'
  • where -o gives on-line result for every interface.
  • grep ether filters out only those interface that have a Ethernet address assigned to it.
  • And awk simply prints the 2nd & 17th column from the lines with a colon in between.

OR

ip -br link | grep -v LOOPBACK | awk '{ print $1 " : " $3 }'

where

  • -br gives the brief information of interfaces.
  • grep -v LOOPBACK ignores the word LOOPBACK that is present only in lo interface.
  • And awk prints first & 3rd column.

Using ifconfig

ifconfig | grep HW | awk '{ print $1" : "$5 }'

where grep HW filters out only those interface that have a hardware address assigned to it.

The Hack

grep HW or grep ether actually ignores the lo because

Loopback interface that doesn't have a HW Address assigned to it.


I made an ugly hacky one liner:

 ip link | awk -F' ' '{print $2 $17}' | paste -d " "  - - | grep -v lo:

If you count the fields using space as separators you will see the fields you need are the 2nd and 17th.

But they will be printed one under the other, the paste places the adjacent lines as colums. The paste fix that placing adjacent lines side by side in a line. I could not find a smart way to avoid getting the lo line so I just excluded it before printing with grep

Testing here:

ip link | awk -F' ' '{print $2 $17}' | paste -d " "  - - | grep -v lo:
enp2s0: 50:9a:4c:b5:af:ea
wlp3s0: e8:9e:b4:66:e3:ea