O cron
é uma excelente ferramenta para agendar a execução automática de tarefas. Com ele podemos criar logs periódicos de sistema, rodar diagnósticos, trocar papéis de parede, checar e-mails, o nível da bateria do notebook, atualizações, exibir notificações na área de trabalho... Mas é aí que começam os problemas.
Especificamente no caso do notify-send
, o cron
irá precisar que pelo menos duas variáveis de ambiente sejam exportadas: DISPLAY
e DBUS_SESSION_BUS_ADDRESS
. Na maioria das vezes, quando queremos agendar uma tarefa que, de algum modo, deverá exibir alguma coisa no ambiente gráfico, basta exportar a varável DISPLAY
na própria linha do crontab
, por exemplo...
$ crontab -e
# No editor que for aberto incluir a linha...
*/10 * * * * DISPLAY=:0 feh --bg-scale --randomize ~/Imagens/wallpapers/*
# Salvar e sair...
Isso irá agendar uma troca de papel de parede aleatória a cada 10 minutos utilizando o programa feh. Eventualmente, DISPLAY
pode não ser o :0
, mas isso é bem fácil de descobrir na tentativa e erro ou, sendo mais técnico, utilizando o comando abaixo no terminal antes de criar o agendamento:
$ echo $DISPLAY
:0
A segunda varável, DBUS_SESSION_BUS_ADDRESS
, já é um pouco mais ardilosa. Geralmente, quando existe apenas um usuário do sistema, seu valor será unix:path=/run/user/1000/bus
, o que pode ser verificado com o comando abaixo:
$ env | grep DBUS_SESSION_BUS_ADDRESS
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
Neste valor, "1000" é o ID do usuário que fez o login (uid
), e isso pode mudar. Para descobrir o seu ID de usuário, basta executar o comando id -u
. No meu caso...
$ id -u
1000
O problema aqui, é que programas como o notify-send
só serão executados se essa variável for passada para o cron
. Isso aqui, funcionaria, mas não para todos os usuários, ou se o seu uid
for diferente de "1000":
*/10 * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus && export DISPLAY=:0 && notify-send "Olá mundo!"
Além de ser uma solução duvidosa, a linha fica horrivelmente longa e ilegível. Uma alternativa bem melhor seria criar um pequeno script e incluí-lo (com o comando source
) nos scripts que serão chamados pelo cron
.
O script seria basicamente assim:
#!/usr/bin/env bash
export DISPLAY=:0
eval "export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/\$(id -u)/bus"
No meu caso, eu salvei o meu na pasta ~/.local/bin
com o nome cron-exp-vars
. Desse modo, sempre que eu quiser utilizar o notify-send
através do cron
, eu crio um script e incluo, via source
, o arquivo cron-exp-vars
.
Por exemplo, para me lembrar de pedir a marmita às 10:30h da manhã de segunda a sexta, eu criei o script cron-pedir-rango
, com o código abaixo:
#!/usr/bin/env bash
# Aqui, eu incluo o script "cron-exp-vars".
# Lembre-se de que "source" ou "." são a mesma coisa.
. $HOME/.local/bin/cron-exp-vars
# Aqui está a linha do "notify-send" com a mensagem
# e o ícone que eu escolhi...
notify-send -u critical \
"Pedir almoço!" \
"Saco vazio não para em pé..." \
-i $HOME/pics/icons/msg-reminder.svg &
# E eu ainda mando tocar um som de alerta...
aplay $HOME/music/sounds/alert-01.wav
Depois, é só incluir no crontab
:
30 10 * * 1-5 ~/.local/bin/cron-pedir-rango
E funciona no meu i3wm!
Claro que a imagem só mostra um teste, já que não são 10:30h da manhã...
Funcionou pra você? Tem uma ideia melhor? Compartilhe conosco nos comentários!
Nenhum comentário:
Postar um comentário
O sistema de comentários do Blogspot é um lixo e praticamente me obriga a liberar ou moderar todos os comentários. Portanto, eu peço perdão antecipadamente caso o seu comentário demore para aparecer.
Mas não se acanhe por causa disso! :-)