无显示器的键盘监控

Cha*_*d G 5 python keyboard-event

正在处理一个使用小键盘和电子墨水显示器的项目,该显示器将在 raspberry pi Zero 上运行。我已经尝试了几个用于 python 的键盘包(pynput,pyxhook),并且已经编写/测试了在我的桌面(ubuntu)上运行良好的简单击键记录器

但是我尝试在没有监视器的情况下在 pi 上运行它们,两个库都死了

DisplayConnectionError: Can't connect to display ":0": [Errno 111] Connection refused
Run Code Online (Sandbox Code Playgroud)

我知道至少 pyxhook 能够捕获鼠标移动,因此它为什么“需要”访问监视器是有道理的。但我想要的只是一种在后台运行但没有连接监视器的进程中捕获键盘输入的方法

库还可以返回具有焦点的当前窗口作为关键事件的一部分,这可能是监视器被捆绑得如此深的另一个原因。我试过了

$export DISPLAY=":0"
Run Code Online (Sandbox Code Playgroud)

没有帮助。

这是 pynput 的简单代码,适用于监视器,但不适用于无头运行(从 SSH 运行)

#!/usr/bin/env python

from pynput import keyboard

def on_press(key):
    print('Key {} pressed.'.format(key))
    if str(key) == 'Key.esc':
        print('Exiting...')
        return False


with keyboard.Listener(on_press = on_press) as listener:
    listener.join()
Run Code Online (Sandbox Code Playgroud)

有没有办法让这些工作,或者可能有不同的方法来解决这个问题。

上述程序失败的完整堆栈跟踪

Traceback (most recent call last):
  File "./keylog.py", line 3, in <module>
    from pynput import keyboard
  File "/usr/local/lib/python2.7/dist-packages/pynput/__init__.py", line 23, in <module>
    from . import keyboard
  File "/usr/local/lib/python2.7/dist-packages/pynput/keyboard/__init__.py", line 49, in <module>
    from ._xorg import KeyCode, Key, Controller, Listener
  File "/usr/local/lib/python2.7/dist-packages/pynput/keyboard/_xorg.py", line 38, in <module>
    from pynput._util.xorg import (
  File "/usr/local/lib/python2.7/dist-packages/pynput/_util/xorg.py", line 38, in <module>
    _check()
  File "/usr/local/lib/python2.7/dist-packages/pynput/_util/xorg.py", line 36, in _check
    display = Xlib.display.Display()
  File "/usr/local/lib/python2.7/dist-packages/Xlib/display.py", line 89, in __init__
    self.display = _BaseDisplay(display)
  File "/usr/local/lib/python2.7/dist-packages/Xlib/display.py", line 71, in __init__
    protocol_display.Display.__init__(self, *args, **keys)
  File "/usr/local/lib/python2.7/dist-packages/Xlib/protocol/display.py", line 90, in __init__
    self.socket = connect.get_socket(name, protocol, host, displayno)
  File "/usr/local/lib/python2.7/dist-packages/Xlib/support/connect.py", line 87, in get_socket
    return mod.get_socket(dname, protocol, host, dno)
  File "/usr/local/lib/python2.7/dist-packages/Xlib/support/unix_connect.py", line 113, in get_socket
    raise error.DisplayConnectionError(dname, str(val))
Xlib.error.DisplayConnectionError: Can't connect to display ":0": [Errno 111] Connection refused
Run Code Online (Sandbox Code Playgroud)

Cha*_*d G 7

好的,我想通了,想我会发布答案。

pythons键盘模块,文档和源代码在这里

如“已知限制”部分所述,(尽管我认为这不是限制!)

“为了避免依赖 X,Linux 部分读取原始设备文件 (/dev/input/input*),但这需要 root。”

所以这显然会带来安全问题,因为程序现在需要 root 权限,但对我来说这不是问题。

pip install keyboard
Run Code Online (Sandbox Code Playgroud)

简单的程序

import keyboard
import time

def key_press(key):
    print(key.name)

keyboard.on_press(key_press)

while True:
    time.sleep(1)
Run Code Online (Sandbox Code Playgroud)

  • 您应该能够通过创建改变这些输入设备文件权限的 udev 规则来避免 root。https://unix.stackexchange.com/questions/72437/how-to-grant-non-root-user-access-to-device-files (2认同)