Os comandos precisam referenciar sua localização. Então notify-send
precisa ser /usr/bin/notify-send
Todos os comandos precisam ter o caminho completo.
Use o comando whereis notify-send
para ver onde seus comandos "vivem"
Eu fiz um script que deveria me notificar quando há um novo capítulo de mangá que estou lendo. Eu usei o comando notify-send para fazer isso. O programa funciona quando estou tentando executá-lo no terminal. A notificação está sendo exibida. No entanto, quando coloquei isso no meu crontab, a notificação não é exibida. Tenho certeza de que o programa está em execução desde que criei um arquivo para mim. O arquivo foi criado, mas a notificação não foi exibida.
Aqui está meu script
#!/bin/bash
#One Piece Manga reminder
#I created a file named .newop that contains the latest chapter.
let new=$(cat ~/.newop)
wget --read-timeout=30 -t20 -O .opreminder.txt http://www.mangareader.net/103/one-piece.html
if (( $(cat .opreminder.txt | grep "One Piece $new" | wc -l) >=1 ))
then
(( new+=1 ))
echo $new
echo $new > ~/.newop
notify-send "A new chapter of One Piece was released."
else
notify-send "No new chapter for One Piece."
notify-send "The latest chapter is still $new."
fi
exit
E aqui está o que eu escrevi no meu crontab
0,15,30,45 12-23 * * 3 /home/jchester/bin/opreminder.sh
Os comandos precisam referenciar sua localização. Então notify-send
precisa ser /usr/bin/notify-send
Todos os comandos precisam ter o caminho completo.
Use o comando whereis notify-send
para ver onde seus comandos "vivem"
As coisas parecem ser diferentes no 13.04, pelo menos no Gnome Shell.
Primeiro, isso é o que env
imprime quando executado da tarefa cron do usuário zzyxy
(não do root):
HOME=/home/zzyxy
LOGNAME=zzyxy
PATH=/usr/bin:/bin
XDG_RUNTIME_DIR=/run/user/zzyxy
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/home/zzyxy
Para fazer com que notify-send
funcione, parece ser necessário definir a variável de ambiente DBUS_SESSION_BUS_ADDRESS
, conforme Comentário de DahitiF em ubuntuforums.org. Basta prefixar o seguinte na sua descrição do trabalho atual:
eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";
Parece não ser necessário definir DISPLAY
.
O comando notify-send
não mostraria a mensagem em sua tela quando iniciado pelo cron.
Basta adicionar a exibição de destino na parte superior do script, por exemplo:
export DISPLAY=:0
Para o Ubuntu 14.04, pelo menos, a resposta do klrmr acima é a resposta correta. Não parece ser necessário definir o DISPLAY ou articular caminhos completos para o envio de notificação ou qualquer outra forma normal em $ PATH.
Abaixo está um script do cron que estou usando para desligar uma máquina virtual quando o estado da bateria de um laptop fica muito baixo. A configuração de linha DBUS_SESSION_BUS_ADDRESS na resposta do klrmr acima é a modificação que finalmente conseguiu que os avisos funcionassem corretamente.
#!/bin/bash
# if virtual machine is running, monitor power consumption
if pgrep -x vmware-vmx; then
bat_path="/sys/class/power_supply/BAT0/"
if [ -e "$bat_path" ]; then
bat_status=$(cat $bat_path/status)
if [ "$bat_status" == "Discharging" ]; then
bat_current=$(cat $bat_path/capacity)
# halt vm if critical; notify if low
if [ "$bat_current" -lt 10 ]; then
/path/to/vm/shutdown/script
echo "$( date +%Y.%m.%d_%T )" >> "/home/user/Desktop/VM Halt Low Battery"
elif [ "$bat_current" -lt 15 ]; then
eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";
notify-send -i "/usr/share/icons/ubuntu-mono-light/status/24/battery-caution.svg" "Virtual machine will halt when battery falls below 10% charge."
fi
fi
fi
fi
exit 0
No meu caso com o Ubuntu 16.04, qualquer caminho explícito era necessário, eu resolvo o problema apenas adicionando
DISPLAY=:0
nas primeiras linhas do crontab, antes da chamada notificar-enviar.
Primeiro culpado é o seu arquivo crontab, você também precisa mencionar o nome do usuário com o qual o script tem que ser executado, melhor mantê-lo como root
0,15,30,45 12-23 * * 3 root /home/jchester/bin/opreminder.sh
e, em seguida, você deve usar o user_name do usuário da GUI dentro do script e pré-anexá-lo para notificar-enviar com "sudo ou su" para executar o comando como um usuário que possui a GUI
exemplo:
su gnome_user_name -c 'notify-send "summary" "body"'
ou
sudo -u gnome_user_name notify-send "summary" "body"
em que gnome_user_name
é o nome de usuário do usuário que iniciou a sessão da GUI
é você quem fez o login, e se você quiser torná-lo uma escolha dinâmica, você pode obtê-lo de
GNOME_USER='ps -eo uname,cmd | grep gnome-session| head -1 | cut -d' ' -f1 '
exemplo:
su $GNOME_USER -c 'notify-send "summary" "body"'
ou
sudo -u $GNOME_USER notify-send "summary" "body"
A maneira como o binário recupera o endereço do dbus parece ter mudado ultimamente. No Ubuntu 15.04 (Vivid Vervet) com "notify-send 0.7.6", as duas variáveis a seguir são necessárias:
export HOME=/home/$notify_user
export DISPLAY=:0.0
A declaração de 'krlmlr' avalia bem e define o endereço correto, mas a caixa de diálogo não será exibida a partir de uma tarefa agendada.
Se o seu script no crontab estiver sendo executado como root, as respostas acima provavelmente não funcionarão. Tente esta função, que funciona bem para mim em 16.04:
notify_all() {
local title=$1
local msg=$2
who | awk '{print $1, $NF}' | tr -d "()" |
while read u d; do
id=$(id -u $u)
. /run/user/$id/dbus-session
export DBUS_SESSION_BUS_ADDRESS
export DISPLAY=$d
su $u -c "/usr/bin/notify-send '$title' '$msg'"
done
}
(Fonte: link )
Melhor confiar no dbus-session
process, ele deve estar em execução para todos os sistemas em que DBUS_SESSION_BUS_ADDRESS
está presente.
Crie um script:
#!/bin/bash
# notify.sh
environs='pidof dbus-daemon | tr ' ' '\n' | awk '{printf "/proc/%s/environ ", $1}''
export DBUS_SESSION_BUS_ADDRESS='cat $environs 2>/dev/null | tr '$ chmod +x ~/notify.sh
' '\n' | grep DBUS_SESSION_BUS_ADDRESS | cut -d '=' -f2-'
export DISPLAY=:0
notify-send "It works!"
Torne-o executável:
* * * * * $HOME/notify.sh
Adicione ao crontab:
#!/bin/bash
# notify.sh
environs='pidof dbus-daemon | tr ' ' '\n' | awk '{printf "/proc/%s/environ ", $1}''
export DBUS_SESSION_BUS_ADDRESS='cat $environs 2>/dev/null | tr '$ chmod +x ~/notify.sh
' '\n' | grep DBUS_SESSION_BUS_ADDRESS | cut -d '=' -f2-'
export DISPLAY=:0
notify-send "It works!"
Isso levou uma eternidade para fazer funcionar no ubuntu 15.10, tive que adicionar uma fonte para obter os usuais env envs normais. minha exibição foi: 1 por algum motivo também. Usando o pid dos primeiros resultados da sessão gnome para a consulta DBUS_SESSION_BUS_ADDRESS.
# Crontab is
* 21 * * * /bin/sh /home/tristik/cron.sh
#!/bin/sh
# cron.sh
# Notifies the user of date and time
source /home/tristik/.bashrc
pid=$(pgrep -u tristik gnome-session | head -n 1)
dbus=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$pid/environ | sed 's/DBUS_SESSION_BUS_ADDRESS=//' )
export DBUS_SESSION_BUS_ADDRESS=$dbus
export HOME=/home/tristik
export DISPLAY=:1
/usr/bin/notify-send 'title' "$(/bin/date)"
Acabei de fazer isso para trabalhar com o desktop canela no Ubuntu 15.10, usando a seguinte receita:
if [ ! -v DBUS_SESSION_BUS_ADDRESS ]; then
pid=$(pgrep -u $LOGNAME cinnamon-sessio)
eval "export $(\grep -z DBUS_SESSION_BUS_ADDRESS /proc/$pid/environ)"
fi
notify-send "$RESUME" "$INFO"
O truque era perceber que 'canela-sessão' é muito longa para o pgrep encontrar:
$ pgrep -u $LOGNAME cinnamon-session
$ pgrep -u $LOGNAME cinnamon
30789
30917
30965
30981
31039
31335
$ ps -a | \grep cinnamon
30789 tty2 00:00:00 cinnamon-sessio
30917 tty2 00:00:02 cinnamon-settin
30965 tty2 00:00:00 cinnamon-launch
30981 tty2 00:04:15 cinnamon
31039 tty2 00:00:00 cinnamon-killer
31335 tty2 00:00:00 cinnamon-screen
$ ps a | \grep cinnamon
4263 pts/1 S+ 0:00 grep cinnamon
30779 tty2 Ssl+ 0:00 /usr/lib/gdm/gdm-x-session --run-script cinnamon-session-cinnamon
30789 tty2 Sl+ 0:00 cinnamon-session --session cinnamon
30917 tty2 Sl+ 0:02 /usr/lib/x86_64-linux-gnu/cinnamon-settings-daemon/cinnamon-settings-daemon
30965 tty2 Sl+ 0:00 /usr/bin/python2 /usr/bin/cinnamon-launcher
30970 tty2 Sl+ 0:00 /usr/lib/x86_64-linux-gnu/cinnamon-settings-daemon/csd-printer
30981 tty2 Sl+ 4:16 cinnamon --replace
31039 tty2 Sl+ 0:00 /usr/bin/python2 /usr/bin/cinnamon-killer-daemon
31335 tty2 Sl+ 0:00 cinnamon-screensaver
$ pgrep -u $LOGNAME cinnamon-sessio
30789
Eu também tive que usar o \ grep porque meu grep tem um alias para
$ alias grep
alias grep='grep -n --color=always'
Tags cron notify-send