When working with network configuration in Linux, distinguishing between physical and virtual interfaces is crucial. Physical interfaces correspond to actual hardware network cards (like eth0, enp3s0), while virtual interfaces include software-defined ones (like docker0, virbr0).
The ip address command provides a type filter, but interestingly lacks a specific type for physical interfaces. The available types are all virtual interface types:
TYPE := { vlan | veth | vcan | vxcan | dummy | ifb | macvlan | macvtap |
bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | lowpan |
gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan | vti |
nlmon | can | bond_slave | ipvlan | geneve | bridge_slave |
hsr | macsec | netdevsim }
Here are several reliable approaches to filter physical interfaces:
Method 1: Using sysfs
ls -l /sys/class/net/ | grep -v virtual
Method 2: Checking device path
ip -o link | awk '{print $2,$(NF-2)}' | grep -v 'virtual' | cut -d: -f1
Method 3: Using ethtool
for intf in $(ip -o link show | awk -F': ' '{print $2}'); do
if ethtool -i $intf 2>/dev/null | grep -q 'driver:'; then
echo $intf
fi
done
The ip command's type filter focuses on interface functionality rather than physicality because:
- Physical interfaces can be reconfigured as different types
- The same hardware may appear as different interface types
- Virtual interfaces can have physical characteristics (like MAC addresses)
Combine ip with other tools to extract physical interface IPs:
for intf in $(ls -l /sys/class/net/ | grep -v virtual | awk '{print $9}'); do
ip -4 addr show dev $intf | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
done
For systems with ip -j (JSON output) support:
ip -j address show | jq -r '.[] | select(.link_type != "loopback" and .ifname | test("^(eth|en|wl)")).ifname'
When working with network interfaces in Linux, it's crucial to distinguish between physical and virtual interfaces. The ip address show
command provides comprehensive interface information, but lacks a direct filter for physical interfaces.
# List all interface types
ip link show | awk -F': ' '/^[0-9]+:/{print $2}'
The ip
command's type filtering focuses on virtual interface types because:
- Physical interfaces are considered the base case
- Virtual interfaces require explicit type declarations
- The kernel treats physical interfaces differently in sysfs
Here are three reliable approaches to filter physical interfaces:
# Method 1: Using sysfs (most reliable)
ls -l /sys/class/net/ | grep -v virtual | grep -Po '(?<= -> ).*\/net\/\K[^/]+'
# Method 2: Checking device presence
ip -o link show | awk -F': ' '{print $2}' | while read intf; do
[ -d "/sys/class/net/$intf/device" ] && echo "$intf";
done
# Method 3: Using ethtool (for Ethernet interfaces)
for intf in $(ip -o link show | awk -F': ' '{print $2}'); do
ethtool -i $intf 2>/dev/null | grep -q "driver:" && echo $intf
done
Combine interface filtering with IP address display:
# Get IPv4 addresses of physical interfaces
for intf in $(ls -l /sys/class/net/ | grep -v virtual | grep -Po '(?<= -> ).*\/net\/\K[^/]+'); do
ip -4 addr show dev $intf | grep -Po '(?<=inet )[\d.]+'
done
Choose based on your specific needs:
- sysfs method: Most reliable for all physical devices
- device directory check: Works for PCI/USB devices
- ethtool method: Best for Ethernet interfaces only