簡體   English   中英

如何在 Linux、Python 中偵聽“插入 USB 設備”事件?

[英]How can I listen for 'usb device inserted' events in Linux, in Python?

我想在 Linux 中為 Amarok 編寫 Python 腳本,以自動將 stackoverflow 播客復制到我的播放器。 當我插入播放器時,它會安裝驅動器,復制任何待處理的播客,然后彈出播放器。 如何收聽“插入”事件? 我已經瀏覽了一遍,但找不到一個很好的例子。

更新 :如評論中所述,最近的發行版不支持Hal,現在的標准是udev,這是一個使用glib loop和udev的小示例,出於歷史原因,我保留Hal版本。

這基本上是pyudev文檔中示例 ,適用於較早版本和glib循環,請注意,應根據您的特定需求自定義過濾器:

import glib

from pyudev import Context, Monitor

try:
    from pyudev.glib import MonitorObserver

    def device_event(observer, device):
        print 'event {0} on device {1}'.format(device.action, device)
except:
    from pyudev.glib import GUDevMonitorObserver as MonitorObserver

    def device_event(observer, action, device):
        print 'event {0} on device {1}'.format(action, device)

context = Context()
monitor = Monitor.from_netlink(context)

monitor.filter_by(subsystem='usb')
observer = MonitorObserver(monitor)

observer.connect('device-event', device_event)
monitor.start()

glib.MainLoop().run()

具有Hal和d-bus的舊版本:

您可以使用D-Bus綁定並收聽DeviceAddedDeviceRemoved信號。 您必須檢查添加設備的功能才能僅選擇存儲設備。

這是一個小示例,您可以刪除評論並嘗試。

import dbus
import gobject

class DeviceAddedListener:
    def __init__(self):

您需要使用系統總線連接到Hal Manager。

        self.bus = dbus.SystemBus()
        self.hal_manager_obj = self.bus.get_object(
                                              "org.freedesktop.Hal", 
                                              "/org/freedesktop/Hal/Manager")
        self.hal_manager = dbus.Interface(self.hal_manager_obj,
                                          "org.freedesktop.Hal.Manager")

您需要將一個偵聽器連接到您感興趣的信號,在本例中為DeviceAdded

        self.hal_manager.connect_to_signal("DeviceAdded", self._filter)

我正在使用基於功能的過濾器。 它可以接受任何volume並且在以下情況下可以調用do_something ,如果您可以閱讀Hal文檔以找到更適合您需要的查詢,或者有關Hal設備屬性的更多信息。

    def _filter(self, udi):
        device_obj = self.bus.get_object ("org.freedesktop.Hal", udi)
        device = dbus.Interface(device_obj, "org.freedesktop.Hal.Device")

        if device.QueryCapability("volume"):
            return self.do_something(device)

示例函數顯示有關卷的一些信息:

     def do_something(self, volume):
        device_file = volume.GetProperty("block.device")
        label = volume.GetProperty("volume.label")
        fstype = volume.GetProperty("volume.fstype")
        mounted = volume.GetProperty("volume.is_mounted")
        mount_point = volume.GetProperty("volume.mount_point")
        try:
            size = volume.GetProperty("volume.size")
        except:
            size = 0

        print "New storage device detectec:"
        print "  device_file: %s" % device_file
        print "  label: %s" % label
        print "  fstype: %s" % fstype
        if mounted:
            print "  mount_point: %s" % mount_point
        else:
            print "  not mounted"
        print "  size: %s (%.2fGB)" % (size, float(size) / 1024**3)

if __name__ == '__main__':
    from dbus.mainloop.glib import DBusGMainLoop
    DBusGMainLoop(set_as_default=True)
    loop = gobject.MainLoop()
    DeviceAddedListener()
    loop.run()

我沒有嘗試自己編寫這樣的程序,但是我只是看了以下兩個鏈接(感謝Google!),我認為這會有所幫助:

特別是,請閱讀有關org.freedesktop.Hal.Manager接口及其DeviceAddedDeviceRemoved事件的信息。 :-)

希望這可以幫助!

這是5行解決方案。

import pyudev

context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='usb')

for device in iter(monitor.poll, None):
    if device.action == 'add':
        print('{} connected'.format(device))
        # do something very interesting here.

將其保存到一個usb_monitor.py的文件中,運行python monitor.py 插入任何USB,它將打印設備詳細信息

→ python usb_monitor.py 
Device('/sys/devices/pci0000:00/0000:00:14.0/usb1/1-6/1-6:1.0') connected
Device('/sys/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0') connected

在Python 3.5上使用pyudev==0.21.0

我認為D-Bus可以像Chris所說的那樣工作,但是如果您使用的是KDE4,則可以以類似於KDE4“新設備通知程序”小程序的方式使用Solid框架。

該applet的C ++源代碼在此處 ,它顯示了如何使用Solid來檢測新設備。 使用PyKDE4為Python綁定到這些庫,如圖所示這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM