64 votes

Notify-send ne fonctionne pas depuis la crontab

J'ai fait un script qui devrait me notifier quand il y a un nouveau chapitre du manga que je suis en train de lire. J'ai utilisé la commande notify-send pour ce faire. Le programme fonctionne lorsque j'essaie de l'exécuter dans le terminal. La notification s'affiche. Cependant, lorsque je l'ai placé dans ma crontab, la notification ne s'affiche pas. Je suis presque sûr que le programme est en cours d'exécution puisque je lui ai demandé de créer un fichier pour moi. Le fichier a été créé, mais la notification ne s'est pas affichée.

Voici mon 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

Et voici ce que j'ai écrit dans ma crontab

0,15,30,45 12-23 * * 3   /home/jchester/bin/opreminder.sh

0voto

Timothy C. Quinn Points 817

Dans le cas ci-dessous, j'appelais notify-send depuis un script Python qui surveille la mémoire des processus car j'ai eu des problèmes avec la croissance de la mémoire de XOrg.

L'exemple ci-dessous devrait fonctionner et n'affiche pas l'adresse de l'utilisateur. warning: command substitution: ignored null byte in input avertissement.

myscript_cron.sh :

#!/bin/bash
echo $0 called: `date`
export USER=`whoami`
export HOME=/home/$USER
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u ${USER} gnome-session | head -n 1)/environ | tr '\0' '\n'| sed 's/DBUS_SESSION_BUS_ADDRESS=//')

cd <path_to_my_script>

/usr/bin/python3.7 ./<my_script>.py 2>&1 1>/dev/null

crontab :

Note : Ran comme crontab -e dans mon compte utilisateur et non sudo

* * * * * <path_to_my_script>/myscript_cron.sh  >> <path_to_my_script>/cron.log 2>&1

J'aime surveiller la sortie des appels cron vers un fichier journal afin de pouvoir déboguer le Shell Shell mais je ne veux pas qu'il soit pollué par le stdout du Shell Python. J'envoie le Shell Python dans un journal séparé.

0voto

Roman Puchkovskiy Points 229

La solution avec réglage DISPLAY=:0.0 a fonctionné pour moi pendant des années. En 20.04, il a soudainement cessé de fonctionner. Il s'est avéré que les coordonnées d'affichage ont changé, c'est maintenant :1 . Donc

export DISPLAY=:1

J'ai résolu le problème.

Le style de la popup est laid, mais c'est une autre histoire.

Mise à jour

Ce que j'ai écrit ci-dessus concernait le cas d'une mise à niveau de 16.04 à 20.04 en passant par 18.04.

Mais quand j'ai réinstallé Ubuntu 20.04 à partir de zéro (en gardant toujours /home/$USER ), il a cessé de fonctionner (probablement, notify-send est maintenant mis en œuvre par un programme différent).

Donc, maintenant le DISPLAY n'est pas pertinente, mais voici ce que je dois définir : DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus .

Ainsi, une ligne dans la crontab pourrait ressembler à ceci :

14 * * * *     DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send 'Hello!'

La fenêtre contextuelle a le même style que lors de l'exécution de l'opération. notify-send à partir d'un émulateur de terminal.

0voto

devgioele Points 1

Car celui qui utilise le poisson Shell Comme moi, voici mon script qui fait essentiellement la même chose que le script bash de @denis.peplin. Je l'utilise pour envoyer un avertissement lorsque la charge de la batterie est faible.

#!/bin/fish

# set environment variables
pidof dbus-daemon | tr ' ' '\n' | while read -l pid
        set environs $environs /proc/$pid/environ
end
set -x DBUS_SESSION_BUS_ADDRESS (cat $environs 2>/dev/null | tr '\0' '\n' | grep DBUS_SESSION_BUS_ADDRESS>
set -x DISPLAY :0

# perform actual job
set capacity (cat /sys/class/power_supply/BAT0/capacity)
if test $capacity -le $argv[1]
        /usr/local/bin/dunstify -u critical -t 10000 "Battery low!" "Plug in asap."
end

Je devais éviter awk car son type de retour est une chaîne contenant deux chemins séparés par un espace. Une variable poisson n'extrait pas les deux chemins, mais stocke la chaîne entière, ce qui entraîne des conflits lors de l'utilisation de la fonction cat $environs . L'utilisation d'une boucle while qui ajoute les chemins à la variable permet d'atteindre le but recherché.

0voto

John Frankland Points 1

Je viens de faire en sorte que cela fonctionne avec le bureau cinnamon sur Ubuntu 15.10, en utilisant la recette suivante :

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"

Le truc était de réaliser que 'cinnamon-session' est trop long pour que pgrep le trouve :

$ 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

J'ai aussi dû utiliser \grep parce que mon grep est aliasé à

$ alias grep
alias grep='grep -n --color=always'

0voto

mivk Points 4379

Si votre script dans la crontab est exécuté en tant que root, les réponses ci-dessus ne fonctionneront probablement pas. Essayez cette fonction, qui fonctionne bien pour moi en 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 
}

( Source : https://unix.stackexchange.com/a/344377/7286 )

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X