[linux] Get MAC address using shell script

Currently all the solution mentioned for getting the MAC address always use eth0. But what if instead of eth0 my interfaces start with eth1. Also on OS X the interface names are different.
Also the interface eth0 may be present but is unused. i.e. not active, it doesn't have an IP.

So is there a way I could get the MAC address for the first available interface that is Active.(i.e. it has an inet address, I even don't want one having inet6).

For E.g

eth0      Link encap:Ethernet  HWaddr <some addr>
          inet6 addr: <some addr> Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:123
          RX packets:123 errors:123 dropped:123 overruns:123 frame:123
          TX packets:123 errors:123 dropped:123 overruns:123 carrier:123
          collisions:123 txqueuelen:123 
          RX bytes:123 (123 MB)  TX bytes:123 (123 KB)
          Interrupt:123 Memory:00000000-00000000

eth1      Link encap:Ethernet  HWaddr <some addr>
          inet addr:<some addr>  Bcast:<some addr>  Mask:<some addr>
          inet6 addr: <some addr> Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:123 Metric:123
          RX packets:123 errors:123 dropped:123 overruns:123 frame:123
          TX packets:123 errors:123 dropped:123 overruns:123 carrier:123
          collisions:123 txqueuelen:123 
          RX bytes:123 (123 MB)  TX bytes:123 (123 KB)
          Interrupt:123 Memory:00000000-00000000

NOTE : I have changed the values of the output.

So in this case I want the HWaddr for eth1 and not eth0. How do I find it ? Also it should work on all the Linux flavours.

This question is related to linux shell mac-address

The answer is


I know that is a little bit dated, but with basic commands, we can take the mac address of an interface:

ip link show eth0 | grep link/ether | awk '{print $2}'

Have a nice day!


On a modern GNU/Linux system you can see the available network interfaces listing the content of /sys/class/net/, for example:

$ ls /sys/class/net/
enp0s25  lo  virbr0  virbr0-nic  wlp2s0

You can check if an interface is up looking at operstate in the device directory. For example, here's how you can see if enp0s25 is up:

$ cat /sys/class/net/enp0s25/operstate
up

You can then get the MAC address of that interface with:

$ cat /sys/class/net/enp0s25/address 
ff:00:ff:e9:84:a5

For example, here's a simple bash script that prints MAC addresses for active interfaces:

#!/bin/bash
# getmacifup.sh: Print active NICs MAC addresses
D='/sys/class/net'
for nic in $( ls $D )
do
    echo $nic
    if  grep -q up $D/$nic/operstate
    then
        echo -n '   '
        cat $D/$nic/address
    fi
done

And here's its output on a system with an ethernet and a wifi interface:

$ ./getmacifup.sh
enp0s25
   ff:00:ff:e9:84:a5
lo
wlp2s0

For details see the Kernel documentation


Remember also that from 2015 most GNU/Linux distributions switched to systemd, and don't use ethX interface naming scheme any more - now they use a more robust naming convention based on the hardware topology, see:


The best Linux-specific solution is to use sysfs:

$ IFACE=eth0
$ read MAC </sys/class/net/$IFACE/address
$ echo $IFACE $MAC
eth0 00:ab:cd:12:34:56

This method is extremely clean compared to the others and spawns no additional processes since read is a builtin command for POSIX shells, including non-BASH shells. However, if you need portability to OS X, then you'll have to use ifconfig and sed methods, since OS X does not have a virtual filesystem interface like sysfs.


Simply run:

ifconfig | grep ether | cut -d " " -f10

OR

ip a | grep ether | cut -d " " -f6

These two example commands will grep all lines with "ether" string and cut the mac address (that we need) following the number spaces (specified in the -f option) of the grepped portion.

Tested on different Linux flavors


Here's an alternative answer in case the ones listed above don't work for you. You can use the following solution(s) as well, which was found here:

ip addr

OR

ip addr show

OR

ip link

All three of these will show your MAC address(es) next to link/ether. I stumbled on this because I had just done a fresh install of Debian 9.5 from a USB stick without internet access, so I could only do a very minimal install, and received

-bash: ifconfig: command not found

when I tried some of the above solutions. I figured somebody else may come across this problem as well. Hope it helps.


Get MAC adress for eth0:

$ cat /etc/sysconfig/network-scripts/ifcfg-eth0 | grep HWADDR | cut -c 9-25

Example:

[me@machine ~]$ cat /etc/sysconfig/network-scripts/ifcfg-eth0 | grep HWADDR | cut -c 9-25
55:b5:00:10:be:10

I have used command hcicongif with two greps to separate the PC Mac address and I saved the MAC address to variable:

PCMAC=$( hciconfig -a | grep -E 'BD Address:' | grep -Eo '[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}' )

You can also use this command to check if MAC address is in valid format. Note, that only big chars A-F are allowed and also you need to add input for this grep command:

grep -E '[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}:[A-F0-9]{2}'


This was the only thing that worked for me on Armbian:

dmesg | grep -oE 'mac=.*\w+' | cut -b '5-'

$ ip route show default | awk '/default/ {print $5}'

return: eth0 (my online interface)

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

return: ec:a8:6b:bd:55:05 (macaddress of the eth0, my online interface)

Terminal image


You can do as follows

ifconfig <Interface ex:eth0,eth1> | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'

Also you can get MAC for all interface as follows

cat /sys/class/net/*/address

For particular interface like for eth0

cat /sys/class/net/eth0/address

None of the above worked for me because my devices are in a balance-rr bond. Querying either would say the same MAC address with ip l l, ifconfig, or /sys/class/net/${device}/address, so one of them is correct, and one is unknown.

But this works if you haven't renamed the device (any tips on what I missed?):

udevadm info -q all --path "/sys/class/net/${device}"

And this works even if you rename it (eg. ip l set name x0 dev p4p1):

cat /proc/net/bonding/bond0

or my ugly script that makes it more parsable (untested driver/os/whatever compatibility):

awk -F ': ' '
         $0 == "" && interface != "" {
            printf "%s %s %s\n", interface, mac, status;
            interface="";
            mac=""
         }; 
         $1 == "Slave Interface" {
            interface=$2
         }; 
         $1 == "Permanent HW addr" {
            mac=$2
         };
         $1 == "MII Status" {
            status=$2
         };
         END {
            printf "%s %s %s\n", interface, mac, status
         }' /proc/net/bonding/bond0

oh, if you want only the mac ether mac address, you can use that:

ifconfig | grep "ether*" | tr -d ' ' | tr -d '\t' | cut -c 6-42

(work on macintosh)

  • ifconfig -- get all info
  • grep -- keep the line with address
  • tr -- clean all
  • cut -- remove the "ether" to have only the address

Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to shell

Comparing a variable with a string python not working when redirecting from bash script Get first line of a shell command's output How to run shell script file using nodejs? Run bash command on jenkins pipeline Way to create multiline comments in Bash? How to do multiline shell script in Ansible How to check if a file exists in a shell script How to check if an environment variable exists and get its value? Curl to return http status code along with the response docker entrypoint running bash script gets "permission denied"

Examples related to mac-address

Get MAC address using shell script Programmatically getting the MAC of an Android device How to get MAC address of your machine using a C program? How can I get the MAC and the IP address of a connected client in PHP? Reliable method to get machine's MAC address in C# How can I programmatically get the MAC address of an iphone MAC addresses in JavaScript