Skip to content
shellmap

Get the MAC address of a network interface

Print the hardware (link-layer) address of one or all network interfaces — for license-binding, WoL setup, DHCP reservation matching, inventory audits, or diagnosing why a switch port shows an unexpected device.

How to get the mac address of a network interface in each shell

Bashunix
ip link show eth0 | awk "/link\/ether/ {print \$2}"

`ip link show INTERFACE` is the modern iproute2 form. The `link/ether` line has the 6-byte MAC. `awk` extracts column 2. For all interfaces in one shot: `ip -br link show` (`-br` = brief, one line per interface). Linux only — macOS/BSD have no `ip` command (BusyBox `ip` exists on Alpine but is a strict subset).

Zshunix
ip link show eth0 | awk "/link\/ether/ {print \$2}"
Fishunix
ip link show eth0 | awk "/link\/ether/ {print \$2}"
PowerShellwindows
(Get-NetAdapter -Name "Ethernet").MacAddress

`Get-NetAdapter` is Windows-only (the cmdlet ships with Windows; pwsh-on-Linux/macOS has no equivalent — fall back to `ip link` via the system shell). Output format is hyphen-separated `00-1A-2B-3C-4D-5E`. To normalize to colon-separated: `((Get-NetAdapter "Ethernet").MacAddress -replace "-",":").ToLower()`. List all: `Get-NetAdapter | Select Name, MacAddress, Status`.

cmd.exewindows
getmac /v /fo list

`getmac.exe` is the cmd-native tool — has been in Windows since XP. `/v` verbose (shows adapter name + connection name), `/fo list` outputs key:value list (vs `table` default vs `csv`). `getmac /s REMOTE_HOST` gets MAC of a remote machine over WMI (requires admin + firewall opens). The output column is "Physical Address" — same as MAC.

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • **`ifconfig` is DEPRECATED on Linux** — has been since ~2015, removed from default install on Fedora / Arch / Alpine / Ubuntu Server. `apt install net-tools` brings it back, but you're fighting the distro. Always use `ip` on Linux: `ip link` (interfaces), `ip addr` (IPs), `ip route` (routing), `ip neigh` (ARP table). On macOS and FreeBSD, `ifconfig` is STILL the canonical tool — `ip` doesn't exist. Cross-platform scripts that need MAC: `if command -v ip >/dev/null; then ip link show "$IFACE" | awk ...; else ifconfig "$IFACE" | awk "/ether/{print \$2}"; fi`. Or just call Python: `python3 -c "import psutil; print(psutil.net_if_addrs()['eth0'][-1].address)"`.
  • **MAC randomization breaks license-tied-to-MAC** — Windows 10+ (`Random hardware addresses` per Wi-Fi network), iOS 14+ (`Private Wi-Fi Address`), Android 10+ (`Use randomized MAC`) all DEFAULT to using a fresh MAC per SSID. This breaks: (a) software licenses keyed to MAC, (b) DHCP reservations that pin IP-by-MAC, (c) network access control allowlists, (d) "trusted device" identification on captive portals. To pin MAC: Windows Settings → Wi-Fi → SSID → "Use random hardware addresses for this network = Off"; iOS Settings → Wi-Fi → ⓘ → "Private Wi-Fi Address" off. Wired Ethernet typically does NOT randomize (Wi-Fi only) — license vendors moving from Wi-Fi-MAC to Ethernet-MAC as workaround. Production: don't key licenses to MAC at all; use a UUID stored in a file + signed.
  • **MAC formatting — six variants, all legal**: `00:1A:2B:3C:4D:5E` (colon, Linux/macOS default), `00-1A-2B-3C-4D-5E` (hyphen, Windows default), `001A.2B3C.4D5E` (dot, Cisco IOS), `001A2B3C4D5E` (no separator, low-level), uppercase vs lowercase. When comparing MACs in scripts: NORMALIZE both sides — strip separators + lowercase: `mac="${MAC//[-:.]/}"; mac="${mac,,}"`. The first 3 bytes are the OUI (manufacturer ID — Wireshark's `manuf` db decodes them: `00:1A:2B` = Apple, `D8:50:E6` = Microsoft Surface, etc.). The 2nd-least-significant bit of the first byte: locally-administered if 1 (randomized/manual), globally-unique if 0 (factory-assigned).
  • **Read your OWN MAC vs another host's MAC — different mechanisms**. Your own: any of the commands above. Another host on the LAN: ARP — first ping/curl to populate ARP table, then `ip neigh show 192.168.1.50` (Linux) / `arp -n 192.168.1.50` (macOS/Linux portable) / `Get-NetNeighbor -IPAddress 192.168.1.50` (pwsh) / `arp -a 192.168.1.50` (cmd). Cross-subnet (different broadcast domain) — you CANNOT get MAC via ARP, you'd need to ssh to the router and check ITS ARP table. WiFi-attached devices not yet seen: `arp-scan -l` (Linux) sweeps the subnet; `nmap -PR -sn 192.168.1.0/24` does ARP-only ping.
  • **Setting a MAC** (not just reading) — `sudo ip link set dev eth0 down; sudo ip link set dev eth0 address 02:11:22:33:44:55; sudo ip link set dev eth0 up` (Linux); `sudo ifconfig en0 ether 02:11:22:33:44:55` (macOS — REQUIRES the interface be DOWN first via `sudo ifconfig en0 down`, AND there's no "set MAC permanently" on macOS — reboots clear it; persist via a launchd plist); `Set-NetAdapter -Name "Ethernet" -MacAddress "021122334455" -Confirm:$false` (pwsh — vendor driver must support it, many consumer NICs do not). When testing: ALWAYS set the locally-administered bit (`02:`/`06:`/`0A:`/`0E:` prefixes) — globally-unique MACs (`00:1A:2B:...`) might collide with a real device on the network.

Related commands

Related tasks