Estou desenvolvendo um aplicativo para não esquecer o pendrive.
Este aplicativo deve bloquear o desligamento se um pendrive estiver conectado à máquina. Conforme este formulário, caso o usuário queira desligar o sistema enquanto um pendrive estiver conectado, o sistema mostra uma notificação para alertar que deve desligar o pendrive para desbloquear o desligamento.
Para detectar o evento de desligamento, defino uma regra de polkit que chama um script para verificar se algum pendrive está conectado ao sistema.
Se houver algum pendrive conectado, a regra do polkit chama para notificar-enviar através do script send_notify.sh
, que executa este comando:
notify-send "Pendrive-Reminder" "Extract Pendrive to enable shutdown" -t 5000
A regra do polkit é esta:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.consolekit.system.stop" ||
action.id == "org.freedesktop.login1.power-off" ||
action.id == "org.freedesktop.login1.power-off-multiple-sessions" ||
action.id == "org.xfce.session.xfsm-shutdown-helper")
{
try{
polkit.spawn(["/usr/bin/pendrive-reminder/check_pendrive.sh", subject.user]);
return polkit.Result.YES;
}catch(error){
polkit.spawn(["/usr/bin/pendrive-reminder/send_notify.sh", subject.user]);
return polkit.Result.NO;
}
}
}
Mas. depois de colocar esta regra de polkit e pressionar o botão de desligamento, meu usuário não recebe nenhuma notificação.
Eu depurei a regra e verifiquei se o segundo script foi executado, mas notify-send
não mostra a notificação para o meu usuário.
Como posso resolver isso?
ATUALIZAR:
Eu tentei modificar o script assim:
#!/bin/bash
user=$1
XAUTHORITY="/home/$user/.Xauthority"
DISPLAY=$( who | grep -m1 $user.*\( | awk '{print $5}' | sed 's/[(|)]//g')
notify-send "Extract Pendrive to enable shutdown" -t 5000
exit 0
O usuário é passado como parâmetro pelo pòlkit
Mas o problema continua
ATUALIZAÇÃO: Acabei de ver esse bug https://bugs.launchpad.net/ubuntu/+source/libnotify/+bug/160598 que não permite enviar notificações como root.
Mais tarde vou testar para modificar a solução alternativa alterando o usuário
UPDATE2: Depois de alterar o código para this. o problema continua:
#!/bin/bash
export XAUTHORITY="/home/$user/.Xauthority"
export DISPLAY=$(cat "/tmp/display.$user")
user=$1
su $user -c 'notify-send "Pendrive Reminder" "Shutdown lock enabled. Disconnect pendrive to enable shutdown" -u critical'
polkit (e
pkexec
) excluem variáveis de ambienteDISPLAY
eXAUTHORITY
que são necessárias para acesso X.notify-send
falha porque não pode acessar o monitor.Na página de manual do pkexec :
Não estou familiarizado com polkit; talvez você possa definir
org.freedesktop.policykit.exec.allow_gui
apenas para esta regra, ou existem outras possibilidades. Desculpe não poder fornecer uma solução pronta.No entanto, o ponto principal é fornecer
DISPLAY
eXAUTHORITY
paranotify-send
.(Não me bata: uma solução suja seria hardcoding
DISPLAY=:0
eXAUTHORITY=...
em seu script de notificação. Esteja ciente de que isso pode falhar se algo mudar).Editar: com base na discussão acima, uma solução alternativa que deve funcionar com vários usuários e sem
XAUTHORITY
:No login do X, um script deve ser executado automaticamente (talvez alguma
.desktop
configuração em~/.config/autostart
):No seu script polkit inclua
@mviereck
Tentei criar um arquivo de política polkit para notificar-enviar, com este conteúdo
coloquei esse arquivo
/usr/share/polkit-1/actions/org.freedesktop.policykit.notify-send.policy
Mas, depois de pressionar o botão desligar, o menu de desligamento demorou muito para ser exibido e a notificação não apareceu
Por fim, criei um cliente dbus, iniciado como usuário, que recebe sinal do systembus e mostra notificação ao usuário.
O código do cliente dbus está em https://github.com/AlmuHS/Pendrive_Reminder/blob/work-in-progress/dbus-client/client.py
No
send-notify.sh
script, eu apenas adicioneiExecutando o cliente dbus como usuário, a notificação é mostrada corretamente
Agora estou tentando que o cliente possa ser iniciado automaticamente quando o usuário conectar o pendrive
Continue em Como iniciar um cliente dbus a partir de um script?