python包psutil有没有办法检测Debian/Ubuntu和OSX上未安装的设备
我正在编写一个python脚本,它使用psutil包来检测USB设备何时插入计算机。但是,我还想检测设备是否已插入但未安装 我正在阅读文档,并假设像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和
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的等效接口)。