有没有办法让python包psutil在Debian / Ubuntu和OSX上检测未安装的设备

时间:2017-10-09 00:21:46

标签: python linux macos psutil

我正在编写一个python脚本,它使用psutil包来检测USB设备何时插入计算机。但是,我还想检测设备是否已插入但未安装。

我正在阅读文档,并假设像current_state = psutil.disk_partitions(all=True)这样的东西会做这样的事情,但是在进一步的检查中它似乎并没有。

是否有其他方法可以让psutil检测未安装的设备?如果没有,那么系统无关的方式/包检测设备是否已插入但未安装?

2 个答案:

答案 0 :(得分:1)

列出卸载的块设备是依赖于操作系统的:这样做的机制在MacOS和Linux之间并不常见,目前,psutil库没有实现这些差异的抽象层。

在Linux上列出所有块设备

以下迭代器将生成Linux上的块设备列表,不包括那些具有分区(可能只想检查分区本身是否已安装)的块设备,以便可以将结果与设备列表进行比较附加到挂载点:

import glob

def linux_block_devices():
    for blockdev_stat in glob.glob('/sys/block/*/stat'):
        blockdev_dir = blockdev_stat.rsplit('/', 1)[0]
        found_parts = False
        for part_stat in glob.glob(blockdev_dir + '/*/stat'):
            yield blockdev_stat.rsplit('/', 2)[-2]
            found_parts = True
        if not found_parts:
            yield blockdev_dir.rsplit('/', 1)[-1]

在MacOS上列出所有块设备

在MacOS上,我没有意识到用于暴露给Python的程序化使用的接口 - 您最终可能会解析命令行输出,如下所示:

import subprocess, re

def mac_block_devices():
    output = subprocess.check_output(['diskutil', 'list'])
    return re.findall('^\s+\d+:.*\s(disk\S*)$', output, flags=re.MULTILINE)

......这个比较粗糙,因为它不排除有孩子的设备;认为这是读者的练习。

将上述任何一项与psutil

组合
import os, psutil

all_block_devices = set(
  linux_block_devices() if os.path.exists('/sys') else mac_block_devices()
)
used_block_devices = set(
    (p.device.replace('/dev/', '') for p in psutil.disk_partitions())
)
unused_block_devices = all_block_devices - used_block_devices

上面将给出一个操作系统上未使用的块设备列表 - 类似于MacOS上的set(['sdb1', 'sdc1']) on Linux, or set(['disk3', 'disk4s1'])

请注意,这是"未使用"在"意义上并未在挂载表中使用"。还有其他几种方法可以使用块设备而不存在于挂载表中(通过应用程序代码直接进行原始访问;交换分区使用;存在于设备映射器中或支持逻辑卷机制;等等),并检测所有这些对于任何一种操作系统都需要大量的接线。

答案 1 :(得分:0)

我最近在OSX上解决了这个问题,并且可能使用hidapi在* nix上(等待进一步测试)。我如何使用它的一个例子如下:

import hid
import pprint

hid_state = hid.enumerate()
pprint.pprint(hid_state)

输出如下:

[ {'interface_number': -1,
'manufacturer_string': 'Apple Inc.',
'path':     b'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/X'
          b'HC1@14000000/HS12@14400000/Apple Internal Keyboard / Trackpad@14'
          b'400000/Apple Internal Keyboard@0/AppleUSBTCKeyboard@14400000,0',
  'product_id': 610,
  'product_string': 'Apple Internal Keyboard / Trackpad',
  'release_number': 549,
  'serial_number': '',
  'usage': 6,
  'usage_page': 1,
  'vendor_id': 1452},
 {'interface_number': -1,
  'manufacturer_string': 'Apple Inc.',
  'path': b'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/X'
          b'HC1@14000000/HS12@14400000/Apple Internal Keyboard / Trackpad@14'
          b'400000/Touchpad@1/AppleUSBMultitouchDriver@14400000,1',
  'product_id': 610,
  'product_string': 'Apple Internal Keyboard / Trackpad',
  'release_number': 549,
  'serial_number': '',
  'usage': 1,
  'usage_page': 65280,
  'vendor_id': 1452},
 {'interface_number': -1,
  'manufacturer_string': 'Apple Inc.',
  'path': b'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/X'
          b'HC1@14000000/HS12@14400000/Apple Internal Keyboard / Trackpad@14'
          b'400000/Touchpad@2/AppleUSBTCButtons@14400000,2',
  'product_id': 610,
  'product_string': 'Apple Internal Keyboard / Trackpad',
  'release_number': 549,
  'serial_number': '',
  'usage': 2,
  'usage_page': 1,
  'vendor_id': 1452},
 {'interface_number': -1,
  'manufacturer_string': '',
  'path': b'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/'
          b'IOPP/UPSB@0/IOPP/DSB1@3/IOPP/UPS0@0/IOPP/pci-bridge@0/IOPP/pci1b'
          b'73,1100@0/AppleUSBXHCIFL1100@00000000/AppleUSB20XHCIPort@0040000'
          b'0/USB Keyboard@00400000/IOUSBHostInterface@1/IOUSBHostHIDDevice@'
          b'00400000,1',
  'product_id': 617,
  'product_string': 'USB Keyboard',
  'release_number': 4368,
  'serial_number': '',
  'usage': 1,
  'usage_page': 12,
  'vendor_id': 1241},
 {'interface_number': -1,
  'manufacturer_string': '',
  'path': b'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/HDEF@1B/A'
          b'ppleHDAController@1B/IOHDACodecDevice@1B,0/IOHDACodecDriver/IOHD'
          b'ACodecFunction@1B,0,1/AppleHDACodecGeneric/AppleHDADriver/AppleM'
          b'ikeyHIDDriver',
  'product_id': 0,
  'product_string': 'Apple Mikey HID Driver',
  'release_number': 0,
  'serial_number': '',
  'usage': 1,
  'usage_page': 12,
  'vendor_id': 0}]

为简洁起见,此示例已经减少,但是遇到的一个问题是同一设备的多个条目,其中只有路径略有不同,示例如下所示:

'path': b'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/X'
b'HC1@14000000/HS12@14400000/Apple Internal Keyboard / Trackpad@14'
b'400000/Touchpad@2/AppleUSBTCButtons@14400000,2',

VS

'path': b'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/X'
b'HC1@14000000/HS12@14400000/Apple Internal Keyboard / Trackpad@14'
b'400000/Apple Internal Keyboard@0/AppleUSBTCKeyboard@14400000,0',

我能够通过使用路径值减去最后一个字符对字典列表进行排序来删除这些副本(因为许多只以不同的",数字"结尾),如下所示:

list({str(v['path'][:-2]): v for v in r}.values())

正如我所提到的,我仍然需要在* nix上进行测试,但是,我可以说它已经很好地在OSX上拾取鼠标和键盘等HID设备,我需要确定它是否能够拿起USB Rubber Duckies等恶意HID设备但标志看起来不错。