如何在Python中获取网络接口卡名称?

Jav*_*oob 21 python networking

我是python编程的新手,所以请耐心等待我.

无论如何要在机器等中获取NIC卡的名称eth0,lo?如果是这样你怎么做?

我已经研究过但到目前为止我只找到了代码来获取IP地址和MAC地址,例如

import socket
socket.gethostbyname(socket.gethostname())
Run Code Online (Sandbox Code Playgroud)

对这些代码的建议真的很感激.谢谢!

小智 27

在Linux上,您只需列出/ sys/class/net /中的链接即可

os.listdir('/sys/class/net/')
Run Code Online (Sandbox Code Playgroud)

不确定这是否适用于所有发行版.


and*_*rew 22

我曾经用过的一个很棒的Python库就是psutil.它可以在Linux,Windows和OSX等其他平台上使用,并且受Python 2.6到3.6的支持.

Psutil提供net_if_addrs()函数,该函数返回一个字典,其中键是NIC名称,value是分配给NIC的每个地址的命名元组列表,包括地址族,NIC地址,网络掩码,广播地址和目标地址.

使用net_if_addrs()它的一个简单示例将打印NIC名称的Python列表:

import psutil

addrs = psutil.net_if_addrs()
print(addrs.keys())
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案.适用于Win/Linux/Mac,是一个记录良好的库,可用于许多其他操作系统内省. (3认同)

Kri*_*sen 17

由于当我搜索这些信息时,谷歌会弹出这个答案,我想我应该添加我的技术来获取可用的接口(以及IP地址).非常好的模块netifaces以便携的方式处理这个问题.

  • @bitinerant 这不在标准库中。它必须先用“pip”安装才能使用。 (3认同)

Arl*_*ren 11

我认为标准库中没有任何东西可以查询这些名称.

如果我在Linux系统上需要这些名称,我会解析输出ifconfig或内容/proc/net/dev.查看此博客条目是否存在类似问题.


yan*_*ng5 10

socket Python 中的模块 >= 3.3:

import socket

# Return a list of network interface information
socket.if_nameindex()
Run Code Online (Sandbox Code Playgroud)

https://docs.python.org/3/library/socket.html#socket.if_nameindex

  • 我想在这里补充一点,Windows 支持是在 3.8 中添加的,而不是 3.3 中。3.3仅支持Linux。 (2认同)

tij*_*jko 6

使用python ctypes可以调用C库函数getifaddrs

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from ctypes import *

class Sockaddr(Structure):
    _fields_ = [('sa_family', c_ushort), ('sa_data', c_char * 14)]

class Ifa_Ifu(Union):
    _fields_ = [('ifu_broadaddr', POINTER(Sockaddr)),
                ('ifu_dstaddr', POINTER(Sockaddr))]

class Ifaddrs(Structure):
    pass

Ifaddrs._fields_ = [('ifa_next', POINTER(Ifaddrs)), ('ifa_name', c_char_p),
                    ('ifa_flags', c_uint), ('ifa_addr', POINTER(Sockaddr)),
                    ('ifa_netmask', POINTER(Sockaddr)), ('ifa_ifu', Ifa_Ifu),
                    ('ifa_data', c_void_p)]


def get_interfaces():
    libc = CDLL('libc.so.6')
    libc.getifaddrs.restype = c_int
    ifaddr_p = pointer(Ifaddrs())
    ret = libc.getifaddrs(pointer((ifaddr_p)))
    interfaces = set()
    head = ifaddr_p
    while ifaddr_p:
        interfaces.add(ifaddr_p.contents.ifa_name)
        ifaddr_p = ifaddr_p.contents.ifa_next
    libc.freeifaddrs(head) 
    return interfaces

if __name__ == "__main__":
    print(get_interfaces())
Run Code Online (Sandbox Code Playgroud)

请注意,尽管此方法不可移植。


nih*_*ser 5

为了补充@Kristian Evensen提到的内容,这里是我用来解决问题的方法.如果您只想获得接口列表,请使用:

interface_list = netifaces.interfaces()
Run Code Online (Sandbox Code Playgroud)

如果您想要一个特定的接口,但不知道最后的数字是什么(即:eth0),请使用:

interface_list = netifaces.interfaces()
interface = filter(lambda x: 'eth' in x,interface_list)
Run Code Online (Sandbox Code Playgroud)

  • @jonas我使用eth作为例子.他们可以用lo代替eth.我相信我给出的答案足以满足OP的要求.不确定这是值得的downvote. (3认同)
  • @jonas第一行获取这些名称. (3认同)

小智 5

就像 David Breuer 所说,你可以在 Linux 上列出目录“/sys/class/net”。(至少在 Fedora 上有效)。如果您需要有关某些接口的详细信息,您可以导航接口的目录以获取更多信息。

def getAllInterfaces():
    return os.listdir('/sys/class/net/')
Run Code Online (Sandbox Code Playgroud)