Udevはスクリプト内でxinputコマンドを実行しません。

Udevはスクリプト内でxinputコマンドを実行しません。

外部マウスを接続すると、自動的にボタンを再マッピングできるようにしてみたいと思います。ボタンを手動で再マップできますか?xinput set-button-map $mouse_id $button_map

しかし、これを自動化するのに問題があります。現在のデバイスが接続されているときにudevにスクリプトを実行させようとしています。私は次の規則を持っています/etc/udev/rules.d/my_rule.rules

ATTRS{idVendor}=="dummy", ATTRS{idProduct}=="dummy", RUN+="/bin/bash /path/to/my_script.sh"

次のようになりますmy_script.sh

#!/bin/bash
out_file=/path/to/out.txt
mouse_id=dummy
button_map=dummy
# button map before
/usr/bin/xinput get-button-map $mouse_id >> $out_file
/usr/bin/xinput set-button-map $mouse_id $button_map
# button map after
/usr/bin/xinput get-button-map $mouse_id >> $out_file

端末でスクリプトを呼び出すと、スクリプトが期待どおりに正しく実行されますが、問題はudev bash環境でxinputがまったく実行されないことです。 3回の呼び出しのうち何も実行されませんでした。そんなことでさえ/usr/bin/xinput >> $out_file役に立ちません。しかし、同様の操作はecho foobar >> $out_file出力をoutファイルに入れます。

あれこれ色々探してみたけどudevルール作成ガイド他の投稿が提案したように、絶対パスへのさまざまな呼び出しをすべて変更しましたが、理解できませんでした。

ベストアンサー1

探し続けて見つけました。この投稿スーパーユーザーstackexchangeは、xinputがDISPLAYおよびXAUTHORITY環境変数を設定する必要があると述べ、スクリプトを変更でき、うまくいきました!しかし、スリープモードを追加し、バックグラウンドで実行する必要がありました。私の最終的なスクリプトは次のとおりです。

my_rule.rules:

ATTRS{idVendor}=="dummy", ATTRS{idProduct}=="dummy", ACTION=="add", RUN+="/path/to/my_sript.sh"

my_script.sh:

#!/usr/bin/bash
out_file=/path/to/out.txt
# run normal if given argument, start new in background else
if [[ $1 ]]
then
    sleep 1
    mouse_id="my_mouse's_id"
    xenv="env DISPLAY=:0 XAUTHORITY=/home/my_name/.Xauthority"
    # button map before
    $xenv /usr/bin/xinput get-button-map "$mouse_id" >> $out_file
    $xenv /usr/bin/xinput set-button-map "$mouse_id" 2 3 2 4 5 6 7 1 9
    # button map after
    $xenv /usr/bin/xinput get-button-map "$mouse_id" >> $out_file
    echo finished >> $out_file
else
    echo running > $out_file
    # run it, but detached in the background
    /path/to/my_script.sh run_normal & 
fi

また、マウスを接続するときにudevがスクリプトを18回呼び出すことを他の人に指摘したかったのですが、それは問題ではないようです。

おすすめ記事