![디스플레이 없이 키보드 모니터링](https://linux55.com/image/128648/%EB%94%94%EC%8A%A4%ED%94%8C%EB%A0%88%EC%9D%B4%20%EC%97%86%EC%9D%B4%20%ED%82%A4%EB%B3%B4%EB%93%9C%20%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81.png)
라즈베리 파이 제로에서 실행되는 키패드와 e-잉크 디스플레이를 사용하는 프로젝트 작업 중입니다. 저는 Python용 여러 키보드 패키지(pynput, pyxhook)를 시도했고 데스크탑(ubuntu)에서 잘 작동하는 간단한 키로거를 작성/테스트했습니다.
하지만 모니터 없이 파이에서 실행하려고 했더니 두 라이브러리가 모두 죽었습니다.
DisplayConnectionError: Can't connect to display ":0": [Errno 111] Connection refused
적어도 pyxhook이 마우스 움직임을 캡처할 수 있다는 것을 알고 있으므로 모니터에 대한 액세스가 "필요"한 이유가 이해됩니다. 하지만 내가 원하는 것은 모니터가 연결되지 않은 채 백그라운드에서 실행되는 프로세스에서 키보드 입력을 캡처하는 방법입니다.
이러한 라이브러리는 현재 주요 이벤트의 일부로 포커스가 있는 창을 반환할 수도 있습니다. 이는 아마도 모니터 바인딩이 그렇게 깊은 또 다른 이유일 것입니다. 나는 전에 시도했다
$export DISPLAY=":0"
도움이 안돼.
다음은 모니터에서 작동하지만 헤드리스 실행 시(SSH에서 실행) 작동하지 않는 간단한 pynput 코드입니다.
#!/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()
이러한 작업을 수행할 수 있는 방법이 있습니까? 아니면 이 문제를 해결하는 다른 방법이 있을 수 있습니다.
위 프로그램 실패의 전체 스택 추적
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
답변1
좋아, 알아냈고 답변을 게시하겠다고 생각했습니다.
Pythons 키보드 모듈, 문서 및 소스 코드여기
"알려진 제한 사항" 섹션에서 언급했듯이 (비록 이것이 제한 사항이라고 생각하지는 않지만!)
"X에 의존하지 않기 위해 Linux 부분은 원시 장치 파일(/dev/input/input*)을 읽습니다. 하지만 이를 위해서는 루트가 필요합니다."
따라서 프로그램에 이제 루트 권한이 필요하므로 이로 인해 분명히 보안 문제가 발생하지만 제가 아는 한 문제는 아닙니다.
pip install keyboard
간단한 절차
import keyboard
import time
def key_press(key):
print(key.name)
keyboard.on_press(key_press)
while True:
time.sleep(1)
답변2
현재 비슷한 문제를 해결하고 있습니다. 나는 이 문제를 해결하는 방법을 알고 있습니다. 하지만 아직 시도하지 않았습니다. 이것을 새로운 질문에 넣어야할지 잘 모르겠습니다.
- 사용자를 자동으로 로그인하는 가상 콘솔 설정
- 콘솔은 대화형 셸(bash)을 표시하지 않지만 키 누르기를 수신하여 MPD로 보내는 프로세스일 뿐입니다.
그게 다야. 여전히 Ctrl-Fx를 사용하여 표준 콘솔로 전환하고 불필요한 MPD 제어 등의 부작용 없이 정상적으로 로그인할 수 있습니다.
아직 해결되지 않은 몇 가지 문제가 있습니다.
모니터가 연결되어 있지 않으면 Linux에서 가상 콘솔을 열 수 있습니까?
이 콘솔을 설정하는 방법은 무엇입니까? /etc/login.defs?
리스너 프로세스에서는 어떤 언어와 라이브러리를 사용합니까(지금까지는 모든 것을 Python으로 구현했습니다)
MPD에 이벤트를 전달하는 방법 (mpc 명령줄 클라이언트 또는 Python mpc 클라이언트 라이브러리를 통해?)
이것을 커뮤니티 위키로 표시하겠습니다. 따라서 누구나 이 답변에 자유롭게 기여할 수 있습니다.
배경: 현재 GPIO 핀을 통해 제어되는 MPD를 사용하여 Raspberry Pi에 헤드리스 오디오 플레이어를 구현했습니다. 이제 키보드로도 제어할 수 있게 되었으면 좋겠습니다.