키보드를 연결하면 활성화되는 UDEV 규칙이 있습니다.
ACTION=="add", DEVPATH=="/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0/0003:046A:0011.00??/input/input??/event[0-9][0-9]*", ATTRS{name}=="HID 046a:0011", ATTRS{phys}=="usb-0000:00:14.0-1/input0", RUN+="/home/*user*/.udev_rule_scripts/cherry_keyboard.sh", SYMLINK+="cherrysymlink"
그래야 한다
/dev/cherrysymlink
정확히 그 일을 하는 심볼릭 링크를 만들고 ,- 쉘 스크립트를 실행하지만 실행되지 않습니다.
디버그 출력은 다음과 같습니다 udevadm test /devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0/0003:046A:0011.0003/input/input18/event17
.
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.
.INPUT_CLASS=kbd
ACTION=add
DEVLINKS=/dev/input/by-id/usb-046a_0011-event-kbd /dev/cherrysymlink /dev/input/by-path/pci-0000:00:14.0-usb-0:1:1.0-event-kbd
DEVNAME=/dev/input/event17
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0/0003:046A:0011.0003/input/input18/event17
ID_BUS=usb
ID_INPUT=1
ID_INPUT_KEY=1
ID_INPUT_KEYBOARD=1
ID_MODEL=0011
ID_MODEL_ENC=0011
ID_MODEL_ID=0011
ID_PATH=pci-0000:00:14.0-usb-0:1:1.0
ID_PATH_TAG=pci-0000_00_14_0-usb-0_1_1_0
ID_REVISION=0100
ID_SERIAL=046a_0011
ID_TYPE=hid
ID_USB_DRIVER=usbhid
ID_USB_INTERFACES=:030101:
ID_USB_INTERFACE_NUM=00
ID_VENDOR=046a
ID_VENDOR_ENC=046a
ID_VENDOR_ID=046a
LIBINPUT_DEVICE_GROUP=3/46a/11/111:usb-0000:00:14.0-1
MAJOR=13
MINOR=81
SUBSYSTEM=input
USEC_INITIALIZED=31155231
run: '/usr/local/bin/cherry.sh'
키보드를 삽입하면 생성됩니다 /dev/cherrysymlink
. 또한 마지막 줄의 디버그 출력은 스크립트가 /usr/local/bin/cherry.sh
실제로 실행되었음을 나타냅니다.
문제는 스크립트가 실제로 실행되지 않는다는 것입니다.
cherry_keyboard.sh
:
#!/bin/bash
xset r rate 150 60
키보드 키의 자동 반복을 변경해야 하지만 동일하게 유지됩니다.
나는 또한 다음을 시도했습니다.
#!/bin/bash
slock
아무 일도하지. 쉘에서 스크립트를 수동으로 실행할 때 모두 작동합니다. 내가 뭘 잘못했나요?
편집하다:
다음과 같이 스크립트를 수정한 후 echo
출력을 dzen2
화면으로 파이프할 수 있습니다.
#!/bin/bash
export DISPLAY=:0
export XAUTHORITY=/home/*user*/.Xauthority
echo 'test' > /home/*user*/.udev_rule_scripts/test
echo 'test' | dzen2 -p 4
xset r rate 150 60
slock
지금까지 처음 두 echo
줄은 잘 작동하고 있습니다. xset
명령이 여전히 slock
작동하지 않습니다.
편집 2:
좀 읽은 후에는 DBUS 및 환경 변수 "DBUS_SESSION_BUS_ADDRESS"와 관련이 있다고 확신합니다. 또한 사용자로 printenv를 실행하면 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
설정됩니다. printenv를 루트로 실행하면 이 변수가 설정되지 않습니다.
그래서 스크립트를 또 수정했습니다.
#!/bin/bash
export DISPLAY=:0
export XAUTHORITY=/home/*user*/.Xauthority
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
echo 'test' > /home/*user*/.udev_rule_scripts/test
echo 'test' | dzen2 -p 4
xset r rate 150 60
slock
불행히도 여전히 작동하지 않습니다.
편집 3:
Giles의 제안에 따라 스크립트에 다음 줄을 추가했습니다.
#!/bin/bash
exec >>/home/*user*/.udev_rule_scripts/test.log 2>&1; echo; date
export DISPLAY=:0
export XAUTHORITY=/home/*user*/.Xauthority
echo 'test' | dzen2 -p 4
xset r rate 150 60
slock
그러면 다음과 같은 오류 메시지가 생성됩니다.test.log
Tue Feb 23 10:14:17 UTC 2016
/home/*user*/.udev_rule_scripts/cherry_keyboard: line 11: 858 Segmentation fault (core dumped) slock
slock
이것은 실행할 수 없는 이유를 (다소) 설명합니다 . 안타깝게도 아무것도 없습니다 xset
.
편집 4:
이번에는 Gilles와 ojs의 제안을 결합했습니다. 이제 오류 메시지가 더 흥미로워졌습니다.
cherry_keyboard.sh
:
#!/bin/bash
exec >>/home/*user*/.udev_rule_scripts/test.log 2>&1; echo; date
export DISPLAY=:0
export XAUTHORITY=/home/*user*/.Xauthority
echo 'test' | dzen2 -p 4
su *user* -c "DISPLAY=:0 xset r rate 150 60"
su *user* -c "DISPLAY=:0 slock"
test.log:
Tue Feb 23 10:37:22 UTC 2016
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 43 requests (37 known processed) with 0 events remaining.
Tue Feb 23 10:38:37 UTC 2016
dzen: cannot open display
xset: unable to open display ":0"
slock: cannot open display
Tue Feb 23 10:40:54 UTC 2016
문제는 다음과 같습니다. 키보드를 연결하면 dzen2
화면에 뭔가 팝업이 나타난 다음 화면이 검게 변합니다. 하지만 slock
키보드로 입력할 때 충돌이 발생하고 화면이 검은색으로 유지되기 때문이 아닙니다(슬록이 뒤에 있을 때와는 달라야 합니다). 다른 애플리케이션(예: )이 moc
아직 실행 중입니다.
이제 이상한 부분은 다음과 같습니다.
시스템을 다시 시작하기 위해 노트북의 전원 버튼을 눌렀을 때(이 경우에는 이것이 유일한 옵션이라고 생각합니다) 종료되기 전에 검은색 화면이 0.5초 동안 사라지고 대신 빨간색 화면이 나타납니다(슬록의 빨간색 화면). 잘못된 비밀번호를 입력했습니다). 따라서 slock이 실제로 실행 중입니다. 그런데 실제로 둘 다 실행 중인데 둘 다 dzen
" 디스플레이를 열 수 없습니다" 라는 오류 메시지가 표시되는 이유는 무엇입니까 ? slock
왜 화면이 충돌합니까? xset
오류 메시지가 다른가요?
대안 cherry_keyboard.sh
:
#!/bin/bash
exec >>/home/*user*/.udev_rule_scripts/test.log 2>&1; echo; date
export DISPLAY=:0
export XAUTHORITY=/home/*user*/.Xauthority
echo 'test' | dzen2 -p 4
su *user* -c "DISPLAY=:0 xset r rate 150 60"
#su *user* -c "DISPLAY=:0 slock"
test.log
:
Tue Feb 23 10:43:36 UTC 2016
그래서 이번에는 오류 메시지가 전혀 없습니다.
하지만 자동 반복은 두 버전 모두 수정되지 않습니다 xset
...
답변1
첫째, 일치 지시어가 심각하게 잘못되었습니다. 더 나은 규칙은 SUBSYSTEM과 USB VID 및 PID에서만 일치하는 것입니다.
그러나 루트가 활성 X 세션을 제어하기 위해 명령을 실행하도록 할 수는 없습니다. 꼭 이 작업을 수행해야 한다면 최소한 $DISPLAY 및 $XAUTHORITY를 가져와야 합니다. 그러나 올바른 해결 방법은 필요할 때 데스크탑 환경의 기본 도구를 사용하여 이러한 명령을 실행하는 것입니다.
답변2
udev에서 실행된 스크립트는 거의 비어 있는 환경에서 실행됩니다. 특정 세션이나 터미널에 연결되지 않습니다.
가장 먼저 해야 할 일은 오류 메시지를 읽는 것입니다. exec >>/var/log/my-udev-script.log 2>&1; echo; date
스크립트 시작 부분에 아래 줄을 추가 하고 스크립트가 실행된 후 확인하세요 #!
./var/log/my-udev-script.log
명령 xset
은X 윈도우 시스템클라이언트이므로 X 서버와 통신해야 합니다. 환경 변수의 값에 따라 어떤 X 서버(많을 수 있음)와 통신해야 하는지 알 수 있습니다 DISPLAY
. DISPLAY
설정하지 않으면 X xset
서버와 통신할 수 없으므로 오류 메시지를 인쇄하고 종료하는 것뿐입니다.
설정 방법을 알아보려면 DISPLAY
필요한 XAUTHORITY
경우 다음을 참조하세요.다른 사용자의 데스크탑에서 루트로 그래픽 프로그램을 시작할 수 있습니까?그리고원격 X 모니터에서 창 열기("모니터를 열 수 없습니다" 이유)?X 서버가 여러 개 있는 경우 무엇을 해야 할지 파악하기 어려울 수 있습니다.
xset이나 slock은 D-Bus를 필요로 하지도 신경 쓰지도 않습니다. 정말로 D-Bus가 필요하다면,고정 주소로 dbus를 시작하는 방법은 무엇입니까?가장 간단한 방법입니다.