No meu Gentoo Linux com dunstify como daemon de notificação e StumpWM como gerenciador de janelas, escrevi o seguinte script bash que tem como objetivo me informar sobre o status da bateria:
#!/bin/bash
#This script notifies you if your battery is under 80% and puts the laptop to sleep in 5min if it is under 50% and isn't plugged in within that time.
if ! [ -z "$(acpi -b | cut -c 25)" ] && [[ $(acpi -b | cut -c 25) -lt 8 ]] && ! [[ "$( acpi -b | cut -c 28)" == "%" ]]
then if ! [ -z "$(acpi -b | cut -c 25)" ] && [[ $(acpi -b | cut -c 25) -lt 5 ]] && ! [[ "$(acpi -b | cut -c 28)" == "%" ]]
then dunstify "Battery <50" "Battery under 50%, will sleep in 5min."
sleep 5m
if ! [ -z "$(acpi -b | cut -c 25)" ] && [[ $(acpi -b | cut -c 25) -lt 5 ]] && ! [[ "$(acpi -b | cut -c 28)" == "%" ]]
then sudo systemctl suspend
fi
else dunstify "Battery <80" "Battery under 80%."
fi
fi
Isso funciona quando eu o aciono manualmente. No entanto, ele deve ser acionado periodicamente pelo systemd a cada 10 minutos ou mais e me avisar se minha bateria estiver fraca. Então eu escrevi o seguinte serviço systemd:
[Unit]
Description=Checks your battery.
RefuseManualStart=no
RefuseManualStop=yes
[Service]
Type=oneshot
ExecStart=/bin/battery
Se a bateria estiver acima de 80% o serviço termina sem problemas, como deveria. Porém, se estiver abaixo de 80% sai com erro. Olhando para o log, encontro o seguinte:
░░ A start job for unit battery.service has begun execution.
░░
░░ The job identifier is 79311.
Jul 10 16:02:54 gentoolaptop battery[537360]: Connecting to D-Bus failed: Unable to autolaunc>Jul 10 16:02:54 gentoolaptop systemd[1]: battery.service: Main process exited, code=exited, s>░░ Subject: Unit process exited
░░ Defined-By: systemd
░░ Support: https://gentoo.org/support/
░░
░░ An ExecStart= process belonging to unit battery.service has exited.
Tenho tentado executar isso como um serviço de usuário, onde recebo esta mensagem, e como um serviço de sistema, onde sou informado de que XDISPLAY e XAUTHORITY não estão configurados. Por que não consegue enviar mensagens quando acionado como um serviço?
O barramento de sessão D-Bus funciona de forma semelhante ao servidor X – pode haver mais de um por sistema, portanto os clientes devem saber o endereço do soquete ao qual se conectar, ou seja, eles precisam
DBUS_SESSION_BUS_ADDRESS=
de qual é o equivalente aproximado deDISPLAY=
.(Isso é diferente do barramento do sistema , que possui um endereço de soquete global, mas só permite a comunicação com os serviços do sistema.)
Portanto, você deve ter…_BUS_ADDRESS aparecendo ao
systemctl --user show-environment
lado de DISPLAY e XAUTHORITY; pode ser mais fácil fazer isso certificando-se de que seu ~/.xinitrc (ou outro script de inicialização do X) chamesystemctl --user import-environment [...]
após iniciar o barramento de sessão.Existem duas maneiras de iniciar um barramento de sessão:
"Barramento de sessão" tradicional: Em um endereço gerado aleatoriamente em /tmp.
"Barramento de usuário" estilo Systemd: Em um local fixo $XDG_RUNTIME_DIR/bus (/run/user/UID/bus).
Seria melhor mudar seu sistema para o segundo método - não tenho muita certeza de como isso é feito no Gentoo, mas acho que requer a construção do dbus com o
systemd
useflag, para que ele instaledbus.service
unidadesdbus.socket
de usuário e remova qualquer uso de dbus-launch ou dbus-run-session do seu ~/.xinitrc ou outros scripts de inicialização do X.Então sua instância systemd --user iniciará automaticamente o barramento no local "bem conhecido" em /run/user (para ser compartilhado entre sua sessão X, todas as suas sessões tty e seus serviços); alguns clientes D-Bus serão capazes de encontrá-lo lá por padrão, mas pam_systemd também definirá DBUS_SESSION_BUS_ADDRESS para esse local, e o próprio systemd --user saberá disso automaticamente.
Parece que o problema pelo qual meu usuário systemd-service pôde se comunicar através do dbus foi que eu estava usando
startx
para iniciar meu gerenciador de janelas, mas não tinha a linhano meu
.xinitrc
, que aparentemente eu deveria ter colocado em uma posição antes da execução do gerenciador de janelas. Com esta linha definida agora, o serviço funciona como deveria.