UDEVはbashスクリプトを部分的にのみ実行します。

UDEVはbashスクリプトを部分的にのみ実行します。

キーボードを接続するとアクティブになる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"

そうしなければならない

  1. /dev/cherrysymlink正確にそれを行うシンボリックリンクを作成し、
  2. シェルスクリプトを実行しますが、実行されません。

デバッグ出力は次のとおりです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

これまでの最初のecho2行はうまく機能しています。xsetコマンドはまだslock機能しません。

編集2:

ちょっと読んだ後は、DBUSと環境変数「DBUS_SESSION_BUS_ADDRESS」に関連していると確信しています。また、ユーザーとしてprintenvを実行するとDBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus設定されます。 printenvをrootとして実行すると、この変数は設定されません。

だからスクリプトを修正しました。

#!/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秒間消え、代わりに赤い画面が表示されます(緑の赤い画面)。無効なパスワードを入力しました)。したがって、スロックは実際に実行中です。しかし、実際に両方が実行されていますが、どちらも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

コマンドxsetXウィンドウシステムクライアントなので、Xサーバーと通信する必要があります。環境変数の値によって、どのXサーバー(多くの場合もあります)と通信する必要があるかがわかりますDISPLAYDISPLAY設定しないと、Xxsetサーバーと通信できないため、エラーメッセージを印刷して終了するだけです。

設定方法については、DISPLAY必要にXAUTHORITY応じて以下をご覧ください。他のユーザーのデスクトップからrootとしてグラフィカルプログラムを起動できますか?そしてリモートXモニターでウィンドウを開く(「モニターを開けません」理由)?Xサーバーが複数ある場合、何をすべきかを把握するのは難しい場合があります。

xsetやslockはD-Busを必要としません。本当にDバスが必要なら、固定アドレスでdbusを起動するには?最も簡単な方法です。

関連情報