我希望使用 udev 枚举计算机上的所有硬盘,特别是 pyudev 来枚举所有内容:
import pyudev
context = pyudev.Context()
for device in context.list_devices(subsystem='block', DEVTYPE='disk'):
print "{}, ({})".format(device.device_node, device.device_type)
这将打印以下内容:
/dev/sdb (disk)
/dev/sdc (disk)
/dev/sda (disk)
/dev/sr0 (disk)
/dev/loop0 (disk)
/dev/loop1 (disk)
/dev/loop2 (disk)
/dev/loop3 (disk)
/dev/loop4 (disk)
/dev/loop5 (disk)
/dev/loop6 (disk)
/dev/loop7 (disk)
/dev/ram0 (disk)
/dev/ram1 (disk)
/dev/ram10 (disk)
/dev/ram11 (disk)
/dev/ram12 (disk)
/dev/ram13 (disk)
/dev/ram14 (disk)
/dev/ram15 (disk)
/dev/ram2 (disk)
/dev/ram3 (disk)
/dev/ram4 (disk)
/dev/ram5 (disk)
/dev/ram6 (disk)
/dev/ram7 (disk)
/dev/ram8 (disk)
/dev/ram9 (disk)
由于我主要关注实际驱动器,而不是光盘驱动器、环回设备或 RAM 设备,因此如何筛选结果以仅获取真实的物理介质?
由于 udev 下的设备管理非常灵活,因此它可能取决于安装在 /lib/udev/rules.d
或 /etc/udev/rules.d
中的 udev 规则,这些规则决定了您可以过滤哪些键。
可以使用 udevadm
获取设备及其关联的 udev 密钥的列表。
sudo udevadm info --export-db
同样,可以修改脚本以输出此信息,如下所示:
#!/usr/bin/env python
import pyudev
context = pyudev.Context()
for device in context.list_devices(subsystem='block', DEVTYPE='disk'):
for key, value in device.iteritems():
print '{key}={value}'.format(key=key, value=value)
print
这将允许您确定哪些键可用于筛选。 在我的 Debian 系统上,一些条目看起来像这样:
# Loop device
UDEV_LOG=3
DEVPATH=/devices/virtual/block/loop0
MAJOR=7
MINOR=0
DEVNAME=/dev/loop0
DEVTYPE=disk
SUBSYSTEM=block
UDISKS_PRESENTATION_NOPOLICY=1
DEVLINKS=/dev/block/7:0
#cdrom
UDEV_LOG=3
DEVPATH=/devices/pci0000:00/0000:00:01.1/host1/target1:0:0/1:0:0:0/block/sr0
MAJOR=11
MINOR=0
DEVNAME=/dev/sr0
DEVTYPE=disk
SUBSYSTEM=block
ID_CDROM=1
ID_CDROM_DVD=1
ID_CDROM_MRW=1
ID_CDROM_MRW_W=1
ID_SCSI=1
ID_VENDOR=VBOX
ID_VENDOR_ENC=VBOXx20x20x20x20
ID_MODEL=CD-ROM
ID_MODEL_ENC=CD-ROMx20x20x20x20x20x20x20x20x20x20
ID_REVISION=1.0
ID_TYPE=cd
ID_BUS=scsi
ID_PATH=pci-0000:00:01.1-scsi-1:0:0:0
GENERATED=1
UDISKS_PRESENTATION_NOPOLICY=0
DEVLINKS=/dev/block/11:0 /dev/scd0 /dev/disk/by-path/pci-0000:00:01.1-scsi-1:0:0:0 /dev/cdrom /dev/dvd
TAGS=:udev-acl:
# hard disk
UDEV_LOG=3
DEVPATH=/devices/pci0000:00/0000:00:0d.0/host2/target2:0:0/2:0:0:0/block/sda
MAJOR=8
MINOR=0
DEVNAME=/dev/sda
DEVTYPE=disk
SUBSYSTEM=block
ID_ATA=1
ID_TYPE=disk
ID_BUS=ata
可以对这些键/值对进行过滤,以仅返回那些真实的磁盘。 例如,UDISKS_PRESENTATION_NOPOLICY
条目可用于过滤掉环路设备。 您可以仔细阅读 udev 规则以确定它如何尝试区分真实/虚拟磁盘。
像这样的东西将过滤掉 cdrom 和循环设备:
devices = []
for device in context.list_devices(subsystem='block', DEVTYPE='disk'):
# Filter out cd drives, loop devices.
if device.get('ID_TYPE', '') == 'cd':
continue
if device.get('UDISKS_PRESENTATION_NOPOLICY', '0') == '1':
continue
devices.append(device)
print "HARD DISKS:"
由于udev
只在 Linux 内核上运行(至少到目前为止(,你可以按代表所有基于 SCSI/SATA 磁盘驱动程序的设备MAJOR number 8
过滤掉。
for device in context.list_devices(MAJOR='8'):
if (device.device_type == 'disk'):
print "{}, ({})".format(device.device_node, device.device_type)
在我的系统上,您的代码输出以下内容:
/dev/sda, (disk)
/dev/sdf, (disk)
/dev/sdb, (disk)
/dev/sdc, (disk)
/dev/sdd, (disk)
/dev/sde, (disk)
/dev/sr0, (disk)
/dev/loop0, (disk)
/dev/loop1, (disk)
/dev/loop2, (disk)
/dev/loop3, (disk)
/dev/loop4, (disk)
/dev/loop5, (disk)
/dev/loop6, (disk)
/dev/loop7, (disk)
按主要编号 8 过滤后,我看到以下输出:
/dev/sda, (disk)
/dev/sdf, (disk)
/dev/sdb, (disk)
/dev/sdc, (disk)
/dev/sdd, (disk)
/dev/sde, (disk)
请注意,您还将在列表中获得USB硬盘驱动器和USB记忆棒,因为它们也倾向于使用相同的SCSI磁盘驱动程序。
我不确定IDE硬盘驱动器是否映射到最新的2.6或3.x内核的sdX
或hdX
。没有IDE硬盘驱动器进行验证,而且我很久没有了。:D
更新:同一设备编号页面列出了/dev/hdX
是IDE硬盘驱动器使用的设备(IDE光盘也可能是?如果你也想过滤这些,我相信你可以做这样的事情:
for device in context.list_devices(DEVTYPE='disk'):
major = device['MAJOR']
if major == '8' or major == '3':
print "{}, ({})".format(device.device_node, device.device_type)