Eu tenho um teclado de laptop ruim e um Lily58 muito melhor, então escrevi um script bash para poder desabilitar o teclado do meu laptop para que eu possa colocar o Lily58 nele e reativá-lo depois. Mas quando eu desativo o teclado do laptop, ele permanece desativado se eu colocar o laptop em suspensão, enquanto eu preferiria que ele fosse reativado automaticamente na retomada. Então eu escrevi um pequeno script bash
#!/bin/bash
fconfig="/home/alex/.keyboard"
id=$(xinput | grep AT | sed -n '2,2p' | awk '{print $7}' | sed 's/[^0-9]*//g')
if [ -f $fconfig ]; then
read -r var< $fconfig
if [ "$var" = "disabled" ]; then
xinput enable $id
echo "enabled" > $fconfig
fi
fi
Isso verifica se "desativado" está no arquivo /home/alex/.keyboard
que rastreia se o teclado está ativado e, se estiver, é executado xinput
para reativar usando o ID obtido ao examinar a saída xinput
da maneira usada na definição de e id
, em seguida, definir /home/alex/.keyboard
como enabled
. Isso funciona como deveria quando eu aciono o script bash do terminal, mas quando eu inicio o serviço systemd
[Unit]
Description=This service enables your keyboard after suspension
PartOf=graphical-session.target
[Service]
Type=oneshot
ExecStart=/home/alex/bash/enable-keyboard
[Install]
WantedBy=multi-user.target
que desejo executar após a suspensão, ele é definido, /home/alex/.keyboard
mas enabled
na verdade não reativa meu teclado. Além disso, journalctl -xeu enable-keyboard.service
não indica nenhum erro:
Jul 17 22:16:25 gentoolaptop systemd[795]: Starting This service enables your keyboard after suspension.
░░ Subject: A start job for unit UNIT has begun execution
░░ Defined-By: systemd
░░ Support: https://gentoo.org/support/
░░
░░ A start job for unit UNIT has begun execution.
░░
░░ The job identifier is 8969.
Jul 17 22:16:25 gentoolaptop systemd[795]: Finished This service enables your keyboard after suspension.
░░ Subject: A start job for unit UNIT has finished successfully
░░ Defined-By: systemd
░░ Support: https://gentoo.org/support/
░░
░░ A start job for unit UNIT has finished successfully.
░░
░░ The job identifier is 8969.
O que está errado?
Editar: se eu colocar uma cláusula no script para imprimir a saída xinput
em um arquivo, a saída consistirá em uma linha vazia.
Editar: a saída de systemctl --user status dbus.socket dbus.service
é
● dbus.socket - D-Bus User Message Bus Socket
Loaded: loaded (/usr/lib/systemd/user/dbus.socket; static)
Active: active (running) since Thu 2024-07-18 17:22:54 CEST; 5 days ago
Triggers: ● dbus.service
Listen: /run/user/1000/bus (Stream)
Tasks: 0 (limit: 47295)
Memory: 4.0K (peak: 1.5M)
CPU: 8ms
CGroup: /user.slice/user-1000.slice/[email protected]/app.slice/dbus.socket
Jul 18 17:22:54 gentoolaptop systemd[830]: Starting D-Bus User Message Bus Socket...
Jul 18 17:22:54 gentoolaptop systemd[830]: Listening on D-Bus User Message Bus Socket.
● dbus.service - D-Bus User Message Bus
Loaded: loaded (/usr/lib/systemd/user/dbus.service; static)
Active: active (running) since Thu 2024-07-18 17:22:54 CEST; 5 days ago
TriggeredBy: ● dbus.socket
Docs: man:dbus-daemon(1)
Main PID: 897 (dbus-daemon)
Tasks: 1 (limit: 47295)
Memory: 1.0M (peak: 1.7M)
CPU: 252ms
CGroup: /user.slice/user-1000.slice/[email protected]/session.slice/dbus.service
└─897 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
Jul 23 16:55:45 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.149' (uid=1000 pid=105378 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 23 17:11:00 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 23 17:19:31 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.152' (uid=1000 pid=106706 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 23 17:21:31 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 23 17:30:31 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.153' (uid=1000 pid=108520 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 23 17:32:31 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 24 14:15:05 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.164' (uid=1000 pid=126615 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 24 14:17:05 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 24 14:26:05 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.165' (uid=1000 pid=127823 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 24 14:28:05 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
A saída de ls -l /run/user/*/bus
é
srw-rw-rw- 1 alex alex 0 2024-07-18 17:22 /run/user/1000/bus
```.
Nota: Esta resposta pressupõe que a variável de ambiente
DISPLAY
eXAUTHORITY
seria importada para o gerenciador de usuários do systemd pelo seu ambiente de desktop e que você sempre efetua login com a mesma conta de usuário.xinput
é um utilitário X. Em outras palavras, é um cliente X. Portanto, você precisará indicar com qual servidor X ele deve se comunicar (mesmo que haja apenas um em execução) com aDISPLAY
variável de ambiente e permitir que ele se conecte a ele com oXAUTHORITY
ambiente.O complicado é que não parece haver uma maneira legal de fazer com que o(s) gerente(s) de usuário(s) conectado(s) obtenha(m) o serviço do usuário durante a suspensão do sistema (e retome). Além disso, tecnicamente você pode ter vários usuários logados e vários servidores X em execução, então não há realmente nenhuma maneira de "melhorar" como as coisas funcionam em um cenário como este, pelo menos não sem confiar em algumas suposições sujas.
Dito isso, você ainda pode "codificar" uma solução, desde que esteja de acordo com essas suposições:
systemd-run --user
é possível no serviço do sistemarunuser
com , portanto não o substitua porUser=
. Além disso, não o use como um serviço de usuário .EDIT: Como parece que de alguma forma o seu
runuser
não funciona conforme o esperado, você pode tentar a seguinte versão:Certifique-se de que
~/.xinitrc
consiste em pelo menos uma linha dessa origem/etc/X11/xinit/xinitrc.d/50-systemd-user.sh
(assumindo que o arquivo existe em seu sistema) antes daexec
linha:Com o serviço habilitado, o script deve ser chamado sempre após a reinicialização do sistema (que é quando
sleep.target
seria interrompido, daí oPartOf=
eExecStop=
).PS Você pode até mesmo codificar
DISPLAY
eXAUTHORITY
dentro do seu script (export
). Nesse casoExecStop=/home/alex/bash/enable-keyboard
deve funcionar.Se você também precisar
/home/alex/bash/enable-keyboard
ser executado no login gráfico, escreva outro serviço para ele (desta vez provavelmente deverá ser um serviço de usuário ):Certifique-se de ativar este serviço com
systemctl --user
. Além disso, funcionaria apenas se o seu ambiente de área de trabalho fosse realmentegraphical-session.target
ativado no login gráfico.(NOTA: quando você usa
startx
, muito provavelmente o alvo não será puxado. Você deve apenas chamar (não a fonte, mesmo que possa ser adequado para isso) seu script antes~/.xinitrc
daexec
linha, ou se você realmente deseja o gerenciador de usuários para chamá-lo, usesystemctl --user
para iniciar o destino ou o serviço em seu~/.xinitrc
(novamente, antes daexec
linha) .A razão pela qual não pode ser um serviço do sistema é que, supondo que o script precise ser executado após o servidor X na sessão do usuário ser iniciado, você precisaria pesquisar o script (ou abusar
Restart=
) e esperar até então. (Mas é claro, há uma chance de você simplesmente fazer com que ele fale com o servidor X do gerenciador de exibição, se houver, e que o efeito seja mantido. Mas então você precisará descobrir e codificar o correspondenteDISPLAY
eXAUTHORITY
, e dependendo de como o gerenciador de exibição "interage" com o systemd, ele pode estar fadado a ser "atrevido" e você precisará de um desagradável "sono 5".)Você pode até mesmo chamar o script com um
xinitrc.d
script, inicialização automática do XDG ou o que quer que funcione no seu DE.Você está certo, o xinput não produz saída. Eu testei isso.
As unidades de serviço do sistema são executadas fora do escopo/ambiente do Xorg.
Você tem que colocar sua unidade
/usr/lib/systemd/user/myservice.service
, então você terá acesso total.O que eu tentei. Criou um serviço myservice.service em
/usr/lib/systemd/user
ou melhor em/home/[username]/.config/systemd/user
meu script de serviço:
Estou lendo um arquivo na pasta tmp chamadosuspension_wakeup . Sesuspension_wakeup
contiver "true" , então ecoe xinput para um arquivo na pasta tmp chamado xinput . Aqui você pode adicionar seu código, em vez de ecoar. então escreva false parasuspension_wakeup .
Vou colocar outro arquivo chamadosuspension_wakeup ( script executável) em
/usr/lib/systemd/system-sleep
este script escreve "true" no arquivosuspension_wakeup na pasta tmp . Isso faz com que a unidade de serviço ecoe o xinput ou faça suas coisas, se você inserir isso.
o serviço é habilitado com:
systemctl --user enable myservice.service
e começou com
systemctl --user start myservice.service
você tem que colocar "--user" depois de "systemctl" para cada comando systemctl
Isso funcionou, toda vez que o computador entra em suspensão e acorda.
Melhor seria deixar o script
/usr/lib/systemd/system-sleep
mudar o teclado. Mas eu tentei e tentei sem solução. Talvez você tenha uma ideia? Deixe-me saber, se você conseguiu.