我如何收听';插入usb设备';Linux中的事件,Python中的事件?
我想在Linux中为Amarok编写一个Python脚本,自动将stackoverflow播客复制到我的播放器上。当我插入播放机时,它将装入驱动器,复制任何挂起的播客,然后弹出播放机。如何收听“插入”事件?我浏览了hald,但找不到一个好的例子。我自己也没有试过编写这样的程序,但我只是查看了以下两个链接(感谢谷歌!),我认为这会有所帮助:我如何收听';插入usb设备';Linux中的事件,Python中的事件?,python,linux,usb,Python,Linux,Usb,我想在Linux中为Amarok编写一个Python脚本,自动将stackoverflow播客复制到我的播放器上。当我插入播放机时,它将装入驱动器,复制任何挂起的播客,然后弹出播放机。如何收听“插入”事件?我浏览了hald,但找不到一个好的例子。我自己也没有试过编写这样的程序,但我只是查看了以下两个链接(感谢谷歌!),我认为这会有所帮助: (其中讨论了如何使用Python访问D-Bus) (讨论HAL如何将事件发布到D-Bus) 特别是,请阅读org.freedesktop.Hal.Mana
- (其中讨论了如何使用Python访问D-Bus)
- (讨论HAL如何将事件发布到D-Bus)
org.freedesktop.Hal.Manager
界面及其DeviceAdded
和DeviceRemoved
事件。:-)
希望这有帮助 我认为D-Bus会像Chris提到的那样工作,但是如果您使用的是KDE4,那么您可能会以类似于KDE4“新设备通知”小程序的方式使用Solid框架
该applet的C++源,它显示了如何使用Solid来检测新设备。使用PyKDE4对这些库进行Python绑定,如图所示。
更新:如评论中所述,Hal在最近的发行版中不受支持,现在的标准是udev,下面是一个使用glib循环和udev的小示例,出于历史原因,我保留了Hal版本 这基本上是相同的,适用于旧版本和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绑定并监听DeviceAdded
和DeviceRemoved
信号。
为了仅选择存储设备,您必须检查添加设备的功能
下面是一个小示例,您可以删除注释并尝试
import dbus
import gobject
class DeviceAddedListener:
def __init__(self):
您需要使用系统总线连接到Hal管理器
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)
我正在使用基于功能的过滤器。它将接受任何卷
,并将调用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()
这里有一个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\u 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
在Python3.5上测试,pyudev==0.21.0 我收到一个错误代码:dbus.exception.DBusException:org.freedesktop.dbus.error.ServiceUnknown:任何.service文件都没有提供org.freedesktop.Hal的名称。你认为你能帮我吗?@EtienneLepage Lepitre Hal现在已经不推荐了,一般来说,这个解决方案已经不起作用了:(添加了使用udev的解决方案。哇,你能相信我们过去在没有宽带连接到internet的设备上收听播客吗?