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

python包psutil有没有办法检测Debian/Ubuntu和OSX上未安装的设备,python,linux,macos,psutil,Python,Linux,Macos,Psutil,我正在编写一个python脚本,它使用psutil包来检测USB设备何时插入计算机。但是,我还想检测设备是否已插入但未安装 我正在阅读文档,并假设像current\u state=psutil.disk\u partitions(all=True)这样的东西会做类似的事情,但是在进一步检查时,它似乎不会这样做 是否有其他方法让psutil检测未安装的设备?如果不能做到这一点,是否存在一种与系统无关的方法/包来检测设备是否已插入但未安装?列出未安装的块设备取决于操作系统:这样做的机制在MacOS和

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

我正在阅读文档,并假设像
current\u state=psutil.disk\u partitions(all=True)
这样的东西会做类似的事情,但是在进一步检查时,它似乎不会这样做


是否有其他方法让psutil检测未安装的设备?如果不能做到这一点,是否存在一种与系统无关的方法/包来检测设备是否已插入但未安装?

列出未安装的块设备取决于操作系统:这样做的机制在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结合使用 以上内容将为您提供一个操作系统上未使用的块设备列表——类似于Linux上的
set(['sdb1','sdc1']),或MacOS上的set(['disk3','disk4s1'])


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

我最近使用
hidapi
在OSX和*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}]
list({str(v['path'][:-2]): v for v in r}.values())
为了简洁起见,减少了此示例,但面临的一个问题是同一设备的多个条目,其中只有路径略有不同,示例如下所示:

'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

通过使用路径值减去最后的字符对dict列表进行排序,我能够删除这些重复项(因为许多重复项仅以不同的“数字”结尾),如下所示:

[ {'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}]
list({str(v['path'][:-2]): v for v in r}.values())

正如我提到的,我仍然需要在*nix上进行测试,但是,我可以说它在OSX上拾取鼠标和键盘等HID设备方面做得很好,我需要确定它是否能够拾取USB橡皮鸭等恶意HID设备,但标识看起来不错。

@jww抱歉,我不确定这怎么不是编程问题,我正在使用一个我遇到问题的特定库编写Python脚本。我对这个问题进行了编辑,使之更清楚一点。@JulianRed,
psutil
不仅是Python库的名称,也是OS本机命令行实用程序包的名称。如果你以一种更明确的方式(在标题中!)提问,你问的是哪一个问题(当然,编辑已经起到了作用!),这可能会减少混乱……也就是说,你所要求的并不是那么琐碎。确定某个设备是“已插入且未安装”意味着询问每个USB设备的类——例如,如果它不是USB存储,那么您就不想安装它。而且设备可以提供具有多个类的端点——如果一个键盘有一个带有驱动程序的USB存储挂载点,你真的想将其检测为未挂载吗?…我想你可以查找未挂载的块设备;这就决定了我们所关心的设备是由操作系统负责的。OTOH,如果您想将其限制在USB支持的未安装的块设备上,那么这意味着还需要实现更多操作系统特定的布线,因此对于任何尚未完成繁重工作的库,我并不感到特别惊讶。(我可以很容易地在Linux上写一个这样做的答案——不需要psutil,直接询问sysfs——但我不知道MacOS的等效接口)。