Udev não está executando o comando xinput dentro do script

Oct 03 2020

Estou tentando fazer com que, ao conectar um mouse externo, possa remapear automaticamente os botões. Posso remapear botões manualmente comxinput set-button-map $mouse_id $button_map

No entanto, estou tendo problemas para tornar isso automático. No momento, estou tentando fazer com que o udev execute um script sempre que o dispositivo estiver conectado. Eu tenho esta regra como /etc/udev/rules.d/my_rule.rules:

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

e se my_script.shparece com isto:

#!/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

O script é executado exatamente como esperado se eu o chamar de um terminal, mas o problema é que no ambiente udev bash o xinput não está sendo executado. Nenhuma das três chamadas para ele faz nada. Mesmo algo como /usr/bin/xinput >> $out_filenão faz nada. No entanto, algo como echo foobar >> $out_filecoloca a saída no arquivo de saída.

Eu estive olhando várias coisas como este guia de regras do udev de escrita e mudei todas as várias chamadas para caminhos absolutos como alguns outros posts sugeriram, mas não fui capaz de descobrir.

Respostas

1 n3wance Oct 04 2020 at 03:26

Continuei procurando e encontrei este post no superusuário stackexchange que diz que xinput precisa ter as variáveis ​​de ambiente DISPLAY e XAUTHORITY definidas, eu fui capaz de modificar meu script e funcionou! No entanto, também tive que adicionar um sleep e fazê-lo funcionar em segundo plano. Aqui está meu roteiro final:

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

Também quero observar para todos que o udev chama o script 18 vezes quando eu conecto o mouse, mas isso não parece ser um problema.