Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检测热插拔事件的python脚本_Python_Linux_Events_Keyboard - Fatal编程技术网

检测热插拔事件的python脚本

检测热插拔事件的python脚本,python,linux,events,keyboard,Python,Linux,Events,Keyboard,我试图使用python来检测鼠标和键盘事件,并在检测过程中容忍热插拔操作。我编写这个脚本是为了在运行时自动检测键盘和鼠标插件,并输出所有键盘和鼠标事件。我使用evdev和pyudev包来实现这个功能。我的脚本大部分工作正常,包括键盘和鼠标事件检测和插件检测。然而,每当我拔出鼠标时,就会发生许多奇怪的事情,我的脚本无法正常工作。我这里有几个困惑 1当鼠标插入系统时,/dev/input/文件夹中会生成两个文件,包括./mouseX和./eventX。我试图通过cat查看两个源代码的输出,确实存在差

我试图使用python来检测鼠标和键盘事件,并在检测过程中容忍热插拔操作。我编写这个脚本是为了在运行时自动检测键盘和鼠标插件,并输出所有键盘和鼠标事件。我使用evdev和pyudev包来实现这个功能。我的脚本大部分工作正常,包括键盘和鼠标事件检测和插件检测。然而,每当我拔出鼠标时,就会发生许多奇怪的事情,我的脚本无法正常工作。我这里有几个困惑

1当鼠标插入系统时,/dev/input/文件夹中会生成两个文件,包括./mouseX和./eventX。我试图通过cat查看两个源代码的输出,确实存在差异,但我不理解为什么linux会有./mouseX,即使./eventX已经存在

2每当我拔掉鼠标时,./mouseX plug事件首先出现,我在evdev中没有使用该事件,这导致脚本失败,因为我在脚本中读取数据的./eventX被同时拔掉,但我只能在下一轮中检测到./eventX。我在脚本中使用了trickvariable I来绕过这个问题,但即使我可以成功删除鼠标设备,select.select开始无休止的输入读取,即使我没有在键盘上键入任何内容

下面列出的脚本是根据来自的答案修改的,事先感谢您的关注

#!/usr/bin/env python

import pyudev
from evdev import InputDevice, list_devices, categorize
from select import select

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

devices = map(InputDevice, list_devices())
dev_paths = []
finalizers = []

for dev in devices:
    if "keyboard" in dev.name.lower():
        dev_paths.append(dev.fn)
    elif "mouse" in dev.name.lower():
        dev_paths.append(dev.fn)

devices = map(InputDevice, dev_paths)
devices = {dev.fd : dev for dev in devices}
devices[monitor.fileno()] = monitor
count = 1

while True:
    r, w, x = select(devices, [], [])

    if monitor.fileno() in r:
        r.remove(monitor.fileno())

        for udev in iter(functools.partial(monitor.poll, 0), None):
            # we're only interested in devices that have a device node
            # (e.g. /dev/input/eventX)
            if not udev.device_node:
                break

            # find the device we're interested in and add it to fds
            for name in (i['NAME'] for i in udev.ancestors if 'NAME' in i):
                # I used a virtual input device for this test - you
                # should adapt this to your needs
                if 'mouse' in name.lower() and 'event' in udev.device_node:
                    if udev.action == 'add':
                        print('Device added: %s' % udev)
                        dev = InputDevice(udev.device_node)
                        devices[dev.fd] = dev
                        break
                    if udev.action == 'remove':
                        print('Device removed: %s' % udev)
                        finalizers.append(udev.device_node)
                        break


    for path in finalizers:
        for dev in devices.keys():
            if dev != monitor.fileno() and devices[dev].fn == path:
                print "delete the device from list"
                del devices[dev]

    for i in r:
        if i in devices.keys() and count != 0:
            count = -1
            for event in devices[i].read():
                count = count + 1
                print(categorize(event))

mouseX和eventX之间的区别通常是eventX是evdev设备,而mouseX是传统设备,例如,它不支持各种evdev ioctl

我不知道你发布的代码有什么问题,但这里有一个代码片段,它做了正确的事情

!/usr/bin/env python 导入pyudev 导入evdev 导入选择 导入系统 导入功能工具 输入错误号 context=pyudev.context monitor=pyudev.monitor.from_netlinkcontext monitor.filter_by subsystem='input' 注意:在我们最初查询evdev之前,先开始监视,以便 有一个插件,我们在evdev.list_设备之后,我们会选择它 监视器。启动 修改此谓词函数以匹配任何您想要匹配的对象 def predd: 返回d.name.lower中的键盘或d.name.lower中的鼠标 填充活动设备映射,从/dev/input/eventXX映射到 输入设备 设备={} 对于mapevdev.InputDevice中的d,evdev.list_设备: 如果是predd: 打印d 设备[d.fn]=d 专用监控装置 设备['monitor']=监视器 尽管如此: rs,,=select.selectdevices.values,[],[] 无条件ping监视器;如果这是假的话 将不执行操作,因为我们通过了零超时。注意 udev事件需要一些时间才能到达我们这里。 对于iterfunctools.partialmonitor.poll中的udev,0,无: 如果不是udev.device\u节点:中断 如果udev.action==“添加”: 如果udev.device_节点不在设备中: 已添加打印设备:%s%udev 尝试: 设备[udev.device\u节点]=evdev.InputDeviceudev.device\u节点 除IOError外,e: udev报告的设备数量超过了可从 埃夫德夫;一种简单的检查方法是查看devinfo ioctl失败 如果e.errno!=errno.ENOTTY:升起 通过 elif udev.action==“删除”: 注意:这个代码路径不经常使用, 因为select会在读取文件时立即触发读取 描述符消失,而udev事件需要一些时间 是时候向我们宣传了。 如果设备中的udev.device\u节点: 打印设备已删除udev:%s%devices[udev.Device\u节点] 删除设备[udev.device\u节点] 对于rs中的r: 你不能从监视器上读取数据 如果r.fileno==monitor.fileno:继续 如果r.fn不在设备中:继续 Select将立即返回fd进行读取(如果需要) 埃诺德夫。所以一定要处理好。 尝试: 对于r中的事件,请阅读: 通过 打印evdev.categorizeevent 除IOError外,e: 如果e.errno!=errno.ENODEV:升起 已删除打印设备:%s%r del设备[r.fn]