21

If I run the command

ip link | awk '{print $2}'

in Ubuntu 18.04, I get this output:

lo:
00:00:00:00:00:00
wlp1s0:
2c:6e:85:bf:01:00
enp2s0:
14:18:77:a3:01:02

I want it formatted like this (without lo)

wlp1s0: 2c:6e:85:bf:01:00
enp2s0: 14:18:77:a3:01:02

How do I do this?

1
  • Interestingly, you can also do it by ifconfig | grep HW | awk '{ print $1" : "$5 }'. Since loopback doesn't have a HW address, grep will ignore lo. Commented May 25, 2018 at 10:45

8 Answers 8

33

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
1
  • 1
    The /sys directory has been a feature of the Linux kernel since before version 2.6 and as such should be available on all distributions. Commented Apr 28, 2020 at 16:49
7

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.

1
  • I liked you patten matching!
    – vfbsilva
    Commented May 25, 2018 at 15:01
4

With no arguments xargs will replace all newlines, tabs and multiple spaces to single space. By adding -n 2 it will slice that line after each second word. So:

ip link | awk '{print $2}' | xargs -n 2
3

[Quick Answer]:

An approach to get the MAC address without knowing the interface name:

cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address

The following command returns interface name:

ip route show default | awk '/default/ {print $5}'
2
  • Only one that worked for me and easy to use ! Still for anyone who is not able to get it. Go to the base directory where sys directory is and use the command Benyamin gave. Commented Sep 1, 2021 at 14:07
  • Won't work if either LAN cable is not connected for ethernet NICs or WLAN isn't associated if it's WLAN device.
    – damkrat
    Commented Oct 21, 2021 at 12:46
2

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
0
2
cat /sys/class/net/*/address

for all devices

There is also naming schema for network devices, e.g. here https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/networking_guide/sec-understanding_the_predictable_network_interface_device_names.

The names have two-character prefixes based on the type of interface:

en for Ethernet,
wl for wireless LAN (WLAN),
ww for wireless wide area network (WWAN).

Therefore one could use cat /sys/class/net/en*/address to print MAC(s) of ethernet NIC(s) only.

1

OVH Ubuntu 18

ifconfig | grep ether | awk '{ print $2 }'
-1

Another simple way to create a table for NIC/MAC data - in my case the Network interface name starts with en

for i in ls /sys/class/net | egrep -i ^en; do echo "$i $(cat /sys/class/net/${i}/address)"; done

1
  • 2
    please check the command. has a mistake
    – acgbox
    Commented Feb 8, 2023 at 23:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .