Acesso ao D-bus da sessão do usuário a partir de seus comandos cron

5

O que é necessário para dar aos comandos do cron acesso ao barramento da sessão (se estiver em execução)?

Ele costumava funcionar para mim, no Debian Stretch (testing) desde a mudança do systemd até relativamente recentemente (pode ter sido mês ou dois atrás). O mais estranho é que, embora eu suspeite que isso seja controlado pela configuração do PAM, a única mudança que aconteceu com /etc/pam.d recentemente foi adicionar algumas chamadas a pam_selinux to pam.d/systemd-user .

Então, o que devo procurar?

    
por Jan Hudec 18.12.2015 / 19:38

1 resposta

7

Isso provavelmente se deve ao fato de que a variável de ambiente DBUS_SESSION_BUS_ADDRESS não é propagada para o ambiente cron.

Pelo menos no Gnome, o ônibus não é "detectável" (conforme documentado na seção "AUTOMATIC LAUNCHING" do dbus-launch(1) man page ) por meio de arquivos em $HOME/.dbus/session-bus . Isso deixa qualquer coisa em execução no seu crontab sem uma maneira de descobrir $DBUS_SESSION_BUS_ADDRESS e entrar em contato com a sessão D-Bus.

Acredito que funcionou no passado, possivelmente devido ao uso de $HOME/.dbus ou a existência de arquivos /tmp/dbus-$TMPNAM referenciados em $DBUS_SESSION_BUS_ADDRESS (que normalmente é definido como algo parecido com unix:abstract=/tmp/dbus-GkJdpPD4sk,guid=0001e69e075e5e2 ). Como a página dbus-cleanup-sockets(1) man explica:

On Linux, this program is essentially useless, because D-Bus defaults to using "abstract sockets" that exist only in memory and don't have a corresponding file in /tmp.

No entanto, podemos usar uma variação da ideia apresentada em um post do ubuntuforum, Anexar à sessão do DBUS existente sobre o SSH , para descobrir a sessão D-Bus de uma sessão de usuário existente na máquina local a partir do ambiente cron e defina $DBUS_SESSION_BUS_ADDRESS de acordo.

Enquanto a técnica usada lá descobre o ambiente de processos comuns como nautilus , pulseaudio e trackerd , e requer que um ou mais deles sejam executados na sessão ativa, eu recomendo uma versão mais básica. abordagem.

Todos os gerenciadores de sessão do ambiente de área de trabalho ( gnome-session , lxsession e kded4 ) têm $DBUS_SESSION_BUS_ADDRESS definido em seu ambiente, mesmo que tenham sido iniciados antes de dbus-daemon e tenham PIDs mais baixos. Então, faz mais sentido usar apenas o gerenciador de sessão correspondente ao seu ambiente de trabalho.

Eu escrevi o seguinte script, colocado em $HOME/bin/test-crontab-dbus.sh , para testar o acesso ao barramento de sessão existente:

#!/bin/sh
SESSION_MANAGER=lxsession
OUTFILE=/tmp/${USER}-cron-dbus.txt

export $(cat /proc/$(pgrep "$SESSION_MANAGER" -u "$USER")/environ \
  |egrep -z '^DBUS_SESSION_BUS_ADDRESS=')

date >> $OUTFILE
dbus-send --session --dest=org.freedesktop.DBus \
   / org.freedesktop.DBus.GetId 2>> $OUTFILE
if test "$?" -eq 0; then
    echo "Success contacting session bus!" >> $OUTFILE
fi

O SESSION_MANAGER=lxsession acima é apropriado para uma sessão da área de trabalho principal em execução no LXDE. No Gnome, você definiria SESSION_MANAGER=gnome-session e, no KDE, usaria SESSION_MANAGER=kded4 .

Se o trabalho no crontab tiver acesso ao barramento da sessão, você verá algo como o seguinte na saída:

Fri Dec 18 15:27:02 EST 2015
Success contacting session bus!

Caso contrário, você verá a saída da mensagem de erro por dbus-send .

Obviamente, você pode substituir qualquer outro método de teste de conectividade ao barramento de sessão, incluindo qualquer operação que você realmente precise executar por meio de uma tarefa cron.

    
por 18.12.2015 / 21:42

Tags