Python:检查网络接口是否启用

11
在Python中,是否有一种方法可以检测给定的网络接口是否已启用?
在我的脚本中,用户指定了一个网络接口,但在执行任何其他操作之前,我想确保该接口已启用并已分配IP地址。
我在Linux上,并且是root。

需要在哪个操作系统上运行?这个脚本需要在不同的操作系统上运行,还是只有特定的一个操作系统? - Gabriel Samfira
抱歉,目前只支持Linux系统。未来我会扩展到OS X和Windows系统,但现在Linux已经足够了。 - Ricky Robinson
3
没问题 :). https://dev59.com/Amgt5IYBdhLWcg3w5her#11736402 <-- 你看过这个吗?被接受的回答适用于Linux系统。netifaces模块是可移植的,并且可以在已测试的操作系统上使用。 - Gabriel Samfira
哇,那个库太棒了!它解决了我所有的问题。谢谢!! - Ricky Robinson
2
我正在使用Linux,而且我是root,听起来就像这是我的房子,如果必要的话,我会把它烧掉!!! - Eliethesaiyan
6个回答

15

该接口可以配置IP地址但未启动,所以接受的答案是错误的。实际上,您需要检查/sys/class/net/<interface>/flags。如果变量flags中的内容,则flags & 0x1是接口是否已启动的判断依据。

根据应用程序的不同,/sys/class/net/<interface>/operstate可能是您真正想要的,但在技术上,接口可能已经启动而operstate是关闭的,例如当没有连接电缆时。

所有这些都是特定于Linux的。


2
警告:在Linux Mint 18.2中,Cinnamon网络管理器小程序控制关闭网络适配器后,它仍然处于UP和可操作状态。但是,它会删除IP地址。 - Harvey

10

根据@Gabriel Samfira的建议,我使用了netifaces。以下函数会在给定接口关联IP地址时返回True。

def is_interface_up(interface):
    addr = netifaces.ifaddresses(interface)
    return netifaces.AF_INET in addr

文档在这里


1
调用上述函数之前的一个有用检查是:if anInterface in netifaces.interfaces() #... - Ricky Robinson
2
不幸的是,这仅适用于IPv6 / AF_INET6的一半:当接口变为RUNNING时,它会获得LLA,但是当相同的接口离线时,LLA仍然存在。 - TheDiveO

7
使用psutil进行回答:
import psutil
import socket

def check_interface(interface):
    interface_addrs = psutil.net_if_addrs().get(interface) or []
    return socket.AF_INET in [snicaddr.family for snicaddr in interface_addrs]

3

使用pyroute2.IPRoute:

from pyroute2 import IPRoute
ip = IPRoute()
state = ip.get_links(ip.link_lookup(ifname='em1'))[0].get_attr('IFLA_OPERSTATE')
ip.close()

使用 pyroute2.IPDB:

from pyroute2 import IPDB
ip = IPDB()
state = ip.interfaces.em1.operstate
ip.release()

2

您可以在/sys/class/net/<interface>/operstate中查看文件的内容。如果内容不是down,则接口已启动。


0
如果问题是关于检查电缆是否连接(FreeBSD);
[status for status in run.cmd(' /usr/local/bin/sudo ifconfig %s ' % interface).split("\t") if status.strip().startswith("status")][0].strip().endswith("active")

目前还没有API支持这个功能 :( ...


如果我们可以简单地读取/sys/class/net/<interface>/operstate,那就有点过度了... - Ricky Robinson
在FreeBSD 11上,“cat:/sys/class/net/em0/operstate:没有那个文件或目录” - myuce
我明白了。是否有类似于“/sys/class/net”的等效路径? - Ricky Robinson
我看不到。我很想知道在FreeBSD中的等效物。 - myuce

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接