Notificar-enviar não funciona no crontab

35

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
    
por user158335 22.05.2013 / 13:35

11 respostas

17

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"

    
por Meer Borg 22.05.2013 / 14:04
25

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 .

    
por krlmlr 17.09.2013 / 10:29
18

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
    
por Martin Höger 27.05.2014 / 08:23
3

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
    
por nmax 21.10.2014 / 02:58
2

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.

    
por Raul R. 26.10.2017 / 23:15
1

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"
    
por Sundeep Borra 26.07.2013 / 09:38
1

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.

    
por tanza 22.06.2015 / 11:36
0

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 )

    
por mivk 12.02.2017 / 11:37
0

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!"
    
por denis.peplin 22.09.2017 / 11:52
0

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)"
    
por Tristik 02.02.2016 / 09:53
0

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'
    
por John Frankland 03.02.2016 / 14:50