질문 1: 환경 변수.

질문 1: 환경 변수.

Wacom Intuos S 2에 대한 버튼 매핑을 정의하는 다음 스크립트가 있습니다.

/usr/local/bin/wacom_intuos_s_2_pad_button_mapping.sh

#!/bin/bash

export DISPLAY=:0
export XAUTHORITY=/home/scriptim/.Xauthority
/usr/bin/sleep 1 # wait for device to be ready
/usr/bin/xsetwacom set 'Wacom Intuos S 2 Pad pad' Button 1 'key -'
/usr/bin/xsetwacom set 'Wacom Intuos S 2 Pad pad' Button 3 'key +'
/usr/bin/xsetwacom set 'Wacom Intuos S 2 Pad pad' Button 8 'key +Ctrl z -Ctrl'
/usr/bin/xsetwacom set 'Wacom Intuos S 2 Pad pad' Button 9 'key +Ctrl +Shift z -Ctrl -Shift'

스크립트를 수동으로 실행하면 제대로 작동합니다.

내 목표는 패드가 삽입될 때마다 이 스크립트를 자동으로 실행하는 것입니다. 나는 다음 udev규칙을 사용해 보았습니다.

/etc/udev/rules.d/10-wacom_intuos_s_2_pad.rules

ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="056a", ATTRS{idProduct}=="033b", RUN+="/usr/local/bin/wacom_intuos_s_2_pad_button_mapping.sh"

그러나 키보드를 연결하면 스크립트가 버튼을 매핑하지 않습니다.


저는 아치 리눅스( 5.5.10-arch1-1) 를 사용하고 있습니다.

$ lsusb
...
Bus 004 Device 015: ID 056a:033b Wacom Co., Ltd CTL-490 [Intuos Draw (S)]
...
$ udevadm info -a -n hidraw0
...
  looking at parent device '/devices/pci0000:00/0000:00:10.0/usb4/4-2':
    KERNELS=="4-2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bmAttributes}=="80"
    ATTRS{bMaxPower}=="498mA"
    ATTRS{manufacturer}=="Wacom Co.,Ltd."
    ATTRS{quirks}=="0x0"
    ATTRS{maxchild}=="0"
    ATTRS{bNumInterfaces}==" 3"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{devpath}=="2"
    ATTRS{ltm_capable}=="no"
    ATTRS{busnum}=="4"
    ATTRS{devnum}=="15"
    ATTRS{tx_lanes}=="1"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{speed}=="12"
    ATTRS{version}==" 2.00"
    ATTRS{product}=="Intuos PS"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{idVendor}=="056a"
    ATTRS{configuration}==""
    ATTRS{devspec}=="(null)"
    ATTRS{urbnum}=="174"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{removable}=="unknown"
    ATTRS{rx_lanes}=="1"
    ATTRS{idProduct}=="033b"
...
$ udevadm test --action="add" /devices/pci0000:00/0000:00:10.0/usb4/4-2
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.

Load module index
Parsed configuration file /usr/lib/systemd/network/99-default.link
Created link configuration context.
Reading rules file: /usr/lib/udev/rules.d/10-dm.rules
Reading rules file: /etc/udev/rules.d/10-wacom_intuos_s_2_pad.rules
...
Reading rules file: /usr/lib/udev/rules.d/65-libwacom.rules
...
Reading rules file: /usr/lib/udev/rules.d/wacom.rules
Invalid inotify descriptor.
DEVPATH=/devices/pci0000:00/0000:00:10.0/usb4/4-2
DEVNAME=/dev/bus/usb/004/015
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=56a/33b/100
TYPE=0/0/0
BUSNUM=004
DEVNUM=015
MAJOR=189
MINOR=398
ACTION=add
SUBSYSTEM=usb
ID_VENDOR=Wacom_Co._Ltd.
ID_VENDOR_ENC=Wacom\x20Co.\x2cLtd.
ID_VENDOR_ID=056a
ID_MODEL=Intuos_PS
ID_MODEL_ENC=Intuos\x20PS
ID_MODEL_ID=033b
ID_REVISION=0100
ID_SERIAL=Wacom_Co._Ltd._Intuos_PS
ID_BUS=usb
ID_USB_INTERFACES=:030000:030102:
ID_VENDOR_FROM_DATABASE=Wacom Co., Ltd
ID_MODEL_FROM_DATABASE=CTL-490 [Intuos Draw (S)]
ID_PATH=pci-0000:00:10.0-usb-0:2
ID_PATH_TAG=pci-0000_00_10_0-usb-0_2
USEC_INITIALIZED=4102997566
run: '/usr/local/bin/wacom_intuos_s_2_pad_button_mapping.sh'
Unload module index
Unloaded link configuration context.
$ journalctl -xe
Mar 22 17:38:55 scriptim systemd-udevd[5927]: 1-1: Process '/usr/local/bin/wacom_intuos_s_2_pad_button_mapping.sh' failed with exit code 255.

답변1

xsetwacom본질적으로 이는 udev 규칙에서 실행할 때와 친숙한 그래픽 터미널에서 실행할 때(환경 변수 등의 차이로 인해) 경쟁 조건과 동작의 차이가 결합된 것입니다.

질문 1: 환경 변수.

두 번째 문제를 먼저 해결해 보겠습니다. 이는 다음 상황과 유사합니다.cronjob에서 실행할 때 쉘 스크립트가 다르게 동작함.

사용자 환경을 udev 환경과 비교하려면 다음을 실행하세요.누구나 env또는 printenv:

printenv > my-env.txt

그래픽 터미널에서 다음을 udev 스크립트에 추가합니다:

/usr/bin/printenv > /tmp/udev-env.txt

my-env.txt그런 다음 및 을 비교할 수 있습니다 udev-env.txt.

xsetwacom어떤 환경 변수가 사용되고 있는지 추론하려면 ,설치하다ltrace그리고다음과 같은 명령을 실행하세요.:

ltrace -f -e getenv -o my-ltrace-01.log xsetwacom set 'Wacom Intuos S 2 Pad pad' Button 1 'key -'

Wacom 장치가 없기 때문에 전체 명령을 실행할 수 없습니다.

$ xsetwacom set 'Wacom Intuos S 2 Pad pad' Button 1 'key -'
Cannot find device 'Wacom Intuos S 2 Pad pad'.

xsetwacom하지만 나가기 전의 거리 만 보면 DISPLAY및 를 사용한다는 것을 알 수 있습니다 XAUTHORITY.

15447 libX11.so.6->getenv("DISPLAY")             = ":0"
15447 libxcb.so.1->getenv("DISPLAY")             = ":0"
15447 libxcb.so.1->getenv("DISPLAY")             = ":0"
15447 libXau.so.6->getenv("XAUTHORITY")          = "/home/nathaniel/.Xauthority"
15447 libX11.so.6->getenv("XLIBBUFFERSIZE")      = nil
15447 libX11.so.6->getenv("XLIB_SKIP_ARGB_VISUALS") = nil
15447 libX11.so.6->getenv("XKB_DEBUG")           = nil
15447 libX11.so.6->getenv("_XKB_OPTIONS_ENABLE") = nil
15447 libX11.so.6->getenv("XKB_DISABLE")         = nil
15447 +++ exited (status 0) +++

이 값은 인쇄하여 찾을 수 있습니다.

$ printf 'DISPLAY=%q\n' "$DISPLAY"
DISPLAY=:0
$ printf 'XAUTHORITY=%q\n' "$XAUTHORITY"
XAUTHORITY=/home/nathaniel/.Xauthority

그런 다음 스크립트 상단에서 정의합니다.

#!/bin/bash

# Just an example, yours will be different.
export DISPLAY=:0
export XAUTHORITY=/home/nathaniel/.Xauthority
sleep 1
# The rest of the script.

다른 이유로 인해 스크립트가 여전히 작동하지 않을 수 있지만 다른 사람들에게는 환경 변수의 차이를 제거하는 것만으로도 충분해 보입니다. 다른 사용자는관련 질문다음과 같이 Ubuntu 18.04에서 실행할 수 있습니다.

두 개의 변수 내보내기를 스크립트에 추가해야 합니다. 하나는 DISPLAY및 입니다 XAUTHORITY. 이는 올바른 X 세션을 식별하고 액세스하는 데 사용됩니다. env일반 사용자로 로그인한 상태에서 실행하면 적절한 값을 얻을 수 있다 .

문제 2: 경쟁 조건.

이제 경쟁 조건이 발생합니다. 이 xsetwacom명령은 X 서버를 사용하여 하드웨어를 인식하므로 준비되기 전에 실행하면 실패하게 됩니다. 이것은 sleep 1한때 충분했지만 더 이상 그렇지 않습니다. (가끔 사람들이 사용하는sleep 2,sleep 3, 또는sleep 4, 특별한 이유는 없습니다. 광범위하게 말하면 이것이 필요하다는 사실이 나를 괴롭힌다 sleep 1. )

장치를 연결하면:

  1. Linux는 장치를 감지하고 udev 규칙에 따라 장치 항목을 생성합니다.
  2. X 서버에서 장치를 감지했습니다.

xsetwacom2단계 이전에는 달릴 수 없습니다 . X가 아직 장치에 대해 알지 못하는 1단계에서 스크립트를 실행하고 있기 때문에 스크립트가 실패합니다.

자일스 "그럼 악한 짓은 그만둬",https://unix.stackexchange.com/a/65792/30049

이것은 모두 훌륭하지만 사람들이 이것을 시도하면 더 이상 작동하지 않습니다.

귀하의 답변에 세부 사항을 찬성했지만 다음과 같은 이유로 올바른지 확실하지 않습니다. sleep몇 초 동안 사용해 보았습니다. 일단 연결되면 태블릿은 1초 이내에 작동을 시작하므로 명령이 실행되면 장치가 감지되어 사용됩니다 X. 그런데 아직도 일을 안 하시나요?

논평통과레드 산드로

귀하의 하드웨어나 운영 체제가 없기 때문에 귀하의 문제를 재현할 수 없습니다. 하지만 여기에 제가 다른 스레드에서 수집한 내용이 있습니다. sleep지연만으로는 충분하지 않습니다. 어떤 사람들은 다음과 같은 해결 방법을 가지고 있습니다.

아마도 내가 본 가장 급진적인 해결책은 다음과 같습니다.링크 스레드시스템 서비스 파일을 사용하십시오.

결국 스크립트를 시작하기 위해 udev 규칙에 의해 트리거된 systemd 서비스를 사용해야 했습니다.

$ cat /etc/udev/rules.d/99-wacom.rules
SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="056a", ENV{ID_MODEL_ID}=="0302", TAG+="systemd"

[...]

TAG+="systemd"장치에 종속되도록 다른 시스템 서비스(시스템 또는 사용자)를 활성화합니다 (장치 단위로 등록, man 참조 systemd.device).

스페루포,https://unix.stackexchange.com/a/290940/30049

관련 정보