I wrote this in order to get a list of network interfaces on Linux. In the past, I have used publicly available methods from, say, ActiveState, which uses ioctl and was annoying to get working under Python 3. This version simply uses regular expressions on the output of ifconfig.
The documentation style used here follows the numpy documentation guide.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Get a list of network interfaces on Linux.
This code is compatible with Python versions 2 and 3.
"""
from collections import namedtuple
import re
import subprocess
def get_interfaces(external=False, ip=False):
"""
Get a list of network interfaces on Linux.
To access the MAC address and/or the IP address, set the relevant keyword
arguments to True.
Parameters
----------
external : bool, optional
Only show external interfaces, and ignore virtual (e.g. loopback)
devices, and return their MAC addresses.
ip : bool, optional
Only show interfaces which are UP and have an IP address, and return
their IPv4 addresses.
Returns
-------
interfaces
list of str containing the interface name by default, or list of
namedtuple containing `name`, `mac`, and `ip` as requested.
Examples
--------
>>> print(get_interfaces())
['eth0', 'lo', 'wlan0']
>>> print(get_interfaces(external=True))
[Interface(name='eth0', mac='a0:b1:c2:d3:e4:f5'), Interface(name='wlan0', ma
c='f5:e4:d3:c2:b1:a0')]
>>> print(get_interfaces(ip=True))
[Interface(name='lo', ip='127.0.0.1'), Interface(name='wlan0', ip='192.168.1
1.2')]
>>> print(get_interfaces(external=True, ip=True))
[Interface(name='wlan0', mac='f5:e4:d3:c2:b1:a0', ip='192.168.11.2')]
"""
name_pattern = "^(\w+)\s"
mac_pattern = ".*?HWaddr[ ]([0-9A-Fa-f:]{17})" if external else ""
ip_pattern = ".*?\n\s+inet[ ]addr:((?:\d+\.){3}\d+)" if ip else ""
pattern = re.compile("".join((name_pattern, mac_pattern, ip_pattern)),
flags=re.MULTILINE)
ifconfig = subprocess.check_output("ifconfig").decode()
interfaces = pattern.findall(ifconfig)
if external or ip:
Interface = namedtuple("Interface", "name {mac} {ip}".format(
mac="mac" if external else "",
ip="ip" if ip else ""))
return [Interface(*interface) for interface in interfaces]
else:
return interfaces
if __name__ == "__main__":
interfaces = get_interfaces(external=True, ip=True)
for interface in interfaces:
print("{name}: {ip}".format(name=interface.name, ip=interface.ip))
annoying to get working under Python 3
? Because the IOCTL method is more efficient (after all it doesn't need to create another process), so if speed is very important... \$\endgroup\$ifname[:15]
on line 10 had to be changed tostr.encode(ifname)
to get it to work. You are correct about the speed; in this case, this function would run once at the start of two scripts when the robot was to be started, so it was not an issue. \$\endgroup\$ipconfig
is deprecated on Linux. Better use theip
command instead. \$\endgroup\$