在我的python代码中,我需要获取连接到Raspberry Pi的“物理” WiFi网络设备的列表

我一直在通过致电:

raw_output = check_output('iw dev', shell=True)

然后从raw_output提取我需要的所有数据

可以,但是在iw help中说Do NOT screenscrape this tool, we don't consider its output stable.以我的方式获取此数据真的不安全吗?如果是,执行此操作的正确方法是什么?

最佳答案

“请勿屏蔽此工具,我们认为它的输出不稳定”的意思是,随着新版本iw的发布,输出格式可能会更改。因此,iw的开发人员警告您,如果根据软件的输出分析来编写软件,则该软件可能会在iw的 future 版本中中断。

以古老的ifconfig命令为例。多年以来,其输出通常采用以下格式:

eth0      Link encap:Ethernet  HWaddr 00:80:C8:F8:4A:51
          inet addr:192.168.99.35  Bcast:192.168.99.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:190312 errors:0 dropped:0 overruns:0 frame:0
          TX packets:86955 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:30701229 (29.2 Mb)  TX bytes:7878951 (7.5 Mb)
          Interrupt:9 Base address:0x5000

尽管它被认为是稳定的(甚至被某些人淘汰和维护),但它在几年前发生了变化,现在看起来像这样:
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.67  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::8e89:a5ff:fe57:103c  prefixlen 64  scopeid 0x20<link>
        ether 8c:89:a5:57:10:3c  txqueuelen 1000  (Ethernet)
        RX packets 2219946  bytes 3178868967 (2.9 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1241676  bytes 102998523 (98.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

...因此,假设我做了一些软件工作,即通过搜索“HWaddr”之后的字符串来查看MAC地址。如今,它已经被破坏了,因为它应该查找“ether”之后的字符串。

但是,只要您不更新iw或对工作进行常规测试,就不会遇到任何问题。

无论如何,解析第三方工具的输出在本质上总是有些脆弱,您只需要意识到这一点即可。例如,输出可能取决于用户的LOCALE设置。现实生活中的示例,我对ifconfig的输出执行的某些脚本在某些用户环境中失败。根本原因:这是在法语语言环境中的输出结果:
eth0      Lien encap:Ethernet  HWaddr 00:FF:F2:58:32:A1
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          Packets reçus:0 erreurs:0 :0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          Octets reçus:0 (0.0 b) Octets transmis:0 (0.0 b)
          Interruption:23 Adresse de base:0x2000

请注意法语的“Packetsreçus”,“erreurs”和“Octetsreçus”,而不是“RX packet”,“errors”和“RX bytes”。

编辑:

所以:



并不是的。您只需要记住,您的软件取决于某些第三方软件的输出字符串,这些字符串有些超出您的控制范围,将来可能会更改。对您而言,这将是常规测试和维护工作,没有什么可悲的,那就是软件寿命。



同样,“否”,但如果您想对此做到防弹:不要依赖于第三方软件的文本输出。这通常涉及编写自己的代码来替换这些工具,这可能是一项艰巨的任务。而且,如果这样做,您将使用一些第三方库,那么库API也会随着时间变化... :-)

编辑2:

在您的情况下,不要依赖iw的输出(即编写自己的“mini iw”),并考虑要使用Python进行编码:

在底层使用C语言编写的iw,也使用libnl(也在C语言中)与内核进行通信,以获取信息/对网络接口(interface)执行操作。

https://www.infradead.org/~tgr/libnl/

您很幸运:似乎有一个 Activity 维护的Python libnl库版本。

https://pypi.python.org/pypi/libnl/0.2.0

因此,该计划将是:
  • 学习iw C源代码以获取netlink/libnl的想法
    为获取/设置您感兴趣的部件而执行的操作。
  • 在代码中使用Python libnl进行复制。

  • (请注意,libnl/netlink被设计为一种非常通用的长期可扩展机制。它实际上是为实现该目标而设计的,以取代即席ioctl。这种通用性带来了一定的复杂性:它可能非常复杂/涉及大量编码以执行甚至是简单的任务。)

    就像我上面写的那样,用自己的代码替换工具可能是一项艰巨的任务。 grep'ing命令的输出只需几分钟即可编写代码,而在这里这可能要花费数天或数周的时间。因此,您必须在“快速而简单但不太干净”和“自包含,干净,可扩展但昂贵”之间做出选择。这取决于:您是在生产工业级的,客户支持的软件,还是公司内部的工具,还是仅仅是为了娱乐而进行的一个周末的业余软件项目。

    08-16 09:14