【问题标题】:How to tell if a usb mass storage device is plugged in using dbus如何判断是否使用 dbus 插入了 USB 大容量存储设备
【发布时间】:2014-01-04 21:06:51
【问题描述】:

我正在制作一个简单的 python 程序来挂载和卸载闪存驱动器,这样我就不需要做更多的事情,只需查看一个列表并选择我想要挂载的内容。现在,我有每个设备的对象和属性列表。我想知道的是我应该查看哪些属性来判断设备是否是 USB 大容量存储设备。我的第一直觉是看“可拆卸”,但是我只插入了一个设备(我的 Kindle),但我得到了两个可拆卸的设备。我注意到的两个属性不同的是 /dev/sdb 有一个空白的“IdLabel”和“IdUsage”。这是我现在拥有的代码:

#!/usr/bin/python

import dbus

def get_devices():
  bus = dbus.SystemBus()
  ud_manager_obj = bus.get_object('org.freedesktop.UDisks',
                                  '/org/freedesktop/UDisks')
  ud_manager = dbus.Interface(ud_manager_obj, 'org.freedesktop.UDisks')

  proplist = []

  for device in ud_manager.EnumerateDevices():
    device_obj = bus.get_object('org.freedesktop.UDisks', device)
    device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
    proplist.append(device_props.GetAll('org.freedesktop.UDisks.Device'))

  for device_props in proplist:
    print '----------'
    print device_props['IdLabel']
    print device_props['DeviceFile']
    print device_props['IdUsage']
    if device_props['DriveCanDetach']:
      print 'Device is detachable'
    else:
      print 'Device is not detachable'

get_devices()

我说的两个输出是:

Kindle
/dev/sdb1
filesystem
Device is detachable
----------

/dev/sdb

Device is detachable

udisk 的结果 --show-info /dev/sdb1

Showing information for /org/freedesktop/UDisks/devices/sdb1
  native-path:                 /sys/devices/pci0000:00/0000:00:1c.3/0000:04:00.0/usb3/3-1/3
-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1                                           
  device:                      8:17
  device-file:                 /dev/sdb1
    presentation:              /dev/sdb1
    by-id:                     /dev/disk/by-id/usb-Kindle_Internal_Storage_90D42204345600JR
-0:0-part1                                                                                
    by-id:                     /dev/disk/by-uuid/386D-5422
    by-path:                   /dev/disk/by-path/pci-0000:04:00.0-usb-0:1:1.0-scsi-0:0:0:0-
part1                                                                                     
  detected at:                 Sat 04 Jan 2014 03:56:35 PM EST
  system internal:             0
  removable:                   0
  has media:                   1 (detected at Sat 04 Jan 2014 03:56:35 PM EST)
    detects change:            0
    detection by polling:      0
    detection inhibitable:     0
    detection inhibited:       0
  is read only:                0
  is mounted:                  0
  mount paths:             
  mounted by uid:              0
  presentation hide:           0
  presentation nopolicy:       0
  presentation name:           
  presentation icon:           multimedia-player
  automount hint:              
  size:                        1432346624
  block size:                  512
  job underway:                no
  usage:                       filesystem
  type:                        vfat
  version:                     FAT32
  uuid:                        386D-5422
  label:                       Kindle
  partition:
    part of:                   /org/freedesktop/UDisks/devices/sdb
    scheme:                    mbr
    number:                    1
    type:                      0x0b
    flags:                    
    offset:                    8192
    alignment offset:          0
    size:                      1432346624
    label:                     
    uuid:                      

udisk 的结果 --show-info /dev/sdb

Showing information for /org/freedesktop/UDisks/devices/sdb
  native-path:                 /sys/devices/pci0000:00/0000:00:1c.3/0000:04:00.0/usb3/3-1/3
-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb                                                
  device:                      8:16
  device-file:                 /dev/sdb
    presentation:              /dev/sdb
    by-id:                     /dev/disk/by-id/usb-Kindle_Internal_Storage_90D42204345600JR
-0:0                                                                                      
    by-path:                   /dev/disk/by-path/pci-0000:04:00.0-usb-0:1:1.0-scsi-0:0:0:0
  detected at:                 Sat 04 Jan 2014 03:56:34 PM EST
  system internal:             0
  removable:                   1
  has media:                   1 (detected at Sat 04 Jan 2014 03:56:34 PM EST)
    detects change:            1
    detection by polling:      1
    detection inhibitable:     1
    detection inhibited:       0
  is read only:                0
  is mounted:                  0
  mount paths:             
  mounted by uid:              0
  presentation hide:           0
  presentation nopolicy:       0
  presentation name:           
  presentation icon:           multimedia-player
  automount hint:              
  size:                        1432354816
  block size:                  512
  job underway:                no
  usage:                       
  type:                        
  version:                     
  uuid:                        
  label:                       
  partition table:
    scheme:                    mbr
    count:                     1
  drive:
    vendor:                    Kindle
    model:                     Internal Storage
    revision:                  0100
    serial:                    90D42204345600JR
    WWN:                       
    detachable:                1
    can spindown:              0
    rotational media:          Yes, unknown rate
    write-cache:               unknown
    ejectable:                 0
    adapter:                   Unknown
    ports:
    similar devices:
    media:                     
      compat:                 
    interface:                 usb
    if speed:                  480000000 bits/s
    ATA SMART:                 not available

所以我想知道检查是否存在 IdLabel 和 IdUsage 是否足以假设某物是 USB 大容量存储设备。

【问题讨论】:

    标签: python dbus


    【解决方案1】:

    如果您可以使用 UDisks2 DBus 接口,答案将非常简单 :-) 首先,似乎 UDisks2(可能还有 UDisks1,但我还没有安装)只处理通过 USB 连接的海量存储设备,完全忽略了 USB 连接的 MTP 设备和其他类型的 USB 设备,如打印机和鼠标。看看:

    现在我连接了 6 个 USB 设备:

    亚历克斯@galene ~ $ /usr/sbin/lsusb | grep -v '根集线器' 总线 001 设备 004:ID 058f:6362 Alcor Micro Corp. 闪存卡读写器 Bus 001 Device 003: ID 09da:000a A4 Tech Co., Ltd 光学鼠标 Opto 510D 总线 008 设备 090:ID 04e8:6860 Samsung Electronics Co., Ltd GT-I9100 电话 [Galaxy S II]、GT-P7500 [Galaxy Tab 10.1] 总线 008 设备 075:ID 04b8:0007 Seiko Epson Corp. 打印机 总线 009 设备 002:ID 058f:6387 Alcor Micro Corp. 闪存驱动器 总线 009 设备 088:ID 1058:1010 Western Digital Technologies, Inc. Elements 外置硬盘

    058f:6362 是一款“一体式”读卡器,目前已插入 SD 卡。 058f:6387 和 1058:1010 分别是真正的 USB 大容量存储设备、闪存和外置硬盘。 04e8:6860 是三星 Galaxy Note1(MTP 设备),其余的是鼠标和打印机。

    我还有一个内置 SATA 驱动器。

    这是当前的udisksctl status 输出(您可能会看到缺少 Galaxy Note):

    型号修订系列设备 -------------------------------------------------- ---------------------- 日立HDT725040VLA360 V5COA7EA VFM301R3196R5F sda 通用闪存盘 8.07 8D0147DF sdb WDC WD1200BEVS-22RST0 04.01G04 WD-WXE108V72690 sdc 通用 USB CF 读卡器 1.01 058F312D81B sde 通用 USB SM 读卡器 1.02 058F312D81B sdf 通用 USB MS 阅读器 1.03 058F312D81B sdg 通用 USB SD 读卡器 1.00 058F312D81B sdd

    要区分可插拔 USB 大容量存储设备和固定驱动器,可以检查 'ConnectedBus' 和 ''Removable' 属性。请注意,还有另一个属性“MediaRemovable”对应于设备的物理媒体。这是选择可移动 USB 大容量存储设备并打印它们的“MediaRemovable”属性的脚本

    亚历克斯@galene ~ $ 猫 导入 dbus > 总线 = dbus.SystemBus() > ud_manager_obj = bus.get_object('org.freedesktop.UDisks2', '/org/freedesktop/UDisks2') > om = dbus.Interface(ud_manager_obj, 'org.freedesktop.DBus.ObjectManager') > 对于 om.GetManagedObjects().iteritems() 中的 k,v: > drive_info = v.get('org.freedesktop.UDisks2.Drive', {}) > 如果 drive_info.get('ConnectionBus') == 'usb' 和 drive_info.get('Removable'): > print("设备路径: %s, MediaRemovable: %s" % (k, drive_info['MediaRemovable'])) > block_devices = [''.join(chr(c) for c in device[dbus.String(u'org.freedesktop.UDisks2.Block')][dbus.String(u'PreferredDev‌​ice')] if chr( c) != '\x00' ) for device in om.GetManagerObjects().values() if dbus.String(u'org.freedesktop.UDisks2.Block') in device] > EOF 设备路径:/org/freedesktop/UDisks2/drives/Generic_USB_SM_Reader_058F312D81B,MediaRemovable:1 设备路径:/org/freedesktop/UDisks2/drives/Generic_Flash_Disk_8D0147DF,MediaRemovable:1 设备路径:/org/freedesktop/UDisks2/drives/Generic_USB_SD_Reader_058F312D81B,MediaRemovable:1 设备路径:/org/freedesktop/UDisks2/drives/WDC_WD1200BEVS_22RST0_WD_WXE108V72690,MediaRemovable:0 设备路径:/org/freedesktop/UDisks2/drives/Generic_USB_CF_Reader_058F312D81B,MediaRemovable:1 设备路径:/org/freedesktop/UDisks2/drives/Generic_USB_MS_Reader_058F312D81B,MediaRemovable:1

    基本上它解决了您要解决的问题。有传言说有 不可移动 USB 连接的存储设备,但我没见过。

    【讨论】:

    • 我知道这是个老问题。但是 udisks2 让我发狂。是否可以以/dev/sdb1/dev/sdc1/dev/sdd1 等格式列出所有 USB 设备?
    • 如果不过滤可插入/不可插入等,命令如下所示:[''.join(chr(c) for c in device[dbus.String(u'org.freedesktop.UDisks2.Block')][dbus.String(u'PreferredDevice')] if chr(c) != '\x00' ) for device in om.GetManagerObjects().values() if dbus.String(u'org.freedesktop.UDisks2.Block') in device]om在上面的代码sn-p中定义。
    • 你可以编辑和你的答案。我不知道在哪里插入上面的代码。
    • 检查block_devices定义
    • 我最终使用了这个代码bus = dbus.SystemBus() ud_manager_obj = bus.get_object('org.freedesktop.UDisks2', '/org/freedesktop/UDisks2') om = dbus.Interface(ud_manager_obj, 'org.freedesktop.DBus.ObjectManager') for k,v in om.GetManagedObjects().iteritems(): drive_info = v.get('org.freedesktop.UDisks2.Block', {}) if drive_info.get('IdUsage') == "filesystem" and not drive_info.get('HintSystem'): print "/dev/" + k[-5:] 我确信它不是优雅的代码。但它有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多