web-dev-qa-db-fra.com

Notify-send ne fonctionne pas depuis crontab

J'ai fait un script qui devrait m'avertir quand il y a un nouveau chapitre du manga que je lis. J'ai utilisé la commande notify-send pour le faire. Le programme fonctionne lorsque j'essaie de l'exécuter dans un terminal. La notification est affichée. Cependant, lorsque j'ai placé ceci dans ma crontab, la notification ne s'affiche pas. Je suis à peu près sûr que le programme est en cours d'exécution depuis que je l'ai créé pour 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
44
user158335

Les commandes doivent référencer leur emplacement. Donc, notify-send doit être /usr/bin/notify-send

Toutes les commandes doivent avoir leur chemin complet.

Utilisez la commande whereis notify-send pour voir où vos commandes sont "actives".

18
Meer Borg

Les choses semblent être différentes le 13.04, du moins dans Gnome Shell.

Premièrement, voici ce que env imprime lorsqu’il est exécuté à partir du travail cron de l’utilisateur zzyxy (et non de la racine):

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

Pour que notify-send fonctionne, il semble nécessaire de définir la variable d'environnement DBUS_SESSION_BUS_ADDRESS, conformément à commentaire de DahitiF sur ubuntuforums.org. Ajoutez simplement ce qui suit à la description de votre travail actuel:

eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";

Il ne semble pas nécessaire de définir DISPLAY.

31
krlmlr

La commande notify-send n'affichera pas le message sur votre écran si elle est lancée par cron. Ajoutez simplement l'affichage cible en haut de votre script, par exemple:

export DISPLAY=:0
24
Martin Höger

Pour Ubuntu 14.04 au moins, la réponse de klrmr ci-dessus est la bonne réponse. Il ne semble pas nécessaire de définir DISPLAY ou d’articuler des chemins complets pour notify-send ou quoi que ce soit normalement dans $ PATH.

Vous trouverez ci-dessous un script cron que j'utilise pour arrêter une machine virtuelle lorsque l'état de la batterie d'un ordinateur portable devient trop faible. Le paramètre de ligne DBUS_SESSION_BUS_ADDRESS dans la réponse de klrmr ci-dessus est la modification qui a finalement permis aux avertissements de fonctionner correctement.

#!/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
5
nmax

Dans mon cas avec Ubuntu 16.04, tout chemin explicite était requis, je résous le problème en ajoutant simplement

AFFICHAGE =: 0

aux premières lignes de la crontab, avant l'appel notify-send.

2
Raul R.

Le premier responsable est votre fichier crontab, vous devez également mentionner le nom d'utilisateur avec lequel le script doit être exécuté. Il est préférable de le conserver en tant que root.

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

puis vous devez utiliser le nom d'utilisateur de l'utilisateur de l'interface graphique dans le script et le préfixer de façon à notifier-envoyer avec "Sudo ou su" pour exécuter la commande en tant qu'utilisateur propriétaire de l'interface graphique.

exemple :

su gnome_user_name -c 'notify-send "summary" "body"'

ou

Sudo -u gnome_user_name notify-send "summary" "body"

gnome_user_name est le nom d'utilisateur de l'utilisateur qui a lancé la session d'interface graphique, c'est vous qui vous êtes connecté. Si vous souhaitez en faire une sélection dynamique, vous pouvez l'obtenir à partir de

GNOME_USER=`ps -eo uname,cmd | grep gnome-session| head -1 | cut -d' ' -f1 `

exemple :

su $GNOME_USER -c 'notify-send "summary" "body"'

ou

Sudo -u $GNOME_USER notify-send "summary" "body"
1
S471

La façon dont le binaire récupère l'adresse dbus semble avoir changé récemment. Sur Ubuntu 15.04 (Vivid Vervet) avec "notify-send 0.7.6", les deux variables suivantes sont nécessaires:

export HOME=/home/$notify_user
export DISPLAY=:0.0

L'instruction de 'krlmlr' évalue correctement et définit l'adresse correcte, mais la boîte de dialogue ne s'ouvre pas à partir d'un travail cron.

1
tanza

Pour tous les scripts crontab utilisant libnotify, j'utilise ceci:

notify_user() {
    local user=$(whoami)
    notify-send -u normal -t 4000 "System Backup" "Starting backup"
}

notify_user # and do other stuff

Cela fonctionne même si j'utilise cron en mode racine.

0
azzamsa

Si votre script dans crontab est exécuté en tant que root, les réponses ci-dessus ne fonctionneront probablement pas. Essayez cette fonction qui me convient très bien 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 )

0
mivk

Cela a pris une éternité pour faire fonctionner ubuntu 15.10, il a fallu ajouter une source pour que les utilisateurs env env normaux. mon affichage était: 1 pour une raison également. Utilisation du pid des premiers résultats de gnome-session pour la recherche 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)"
0
Tristik

Mieux vaut s'appuyer sur le processus dbus-session, il devrait être en cours d'exécution pour tous les systèmes où DBUS_SESSION_BUS_ADDRESS est présent.

Créez un 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 '\0' '\n' | grep DBUS_SESSION_BUS_ADDRESS | cut -d '=' -f2-`
export DISPLAY=:0

notify-send "It works!"

Rendez-le exécutable:

$ chmod +x ~/notify.sh

Ajoutez-le à crontab:

* * * * * $HOME/notify.sh
0
denis.peplin

Je viens de recevoir ceci pour travailler avec le bureau cannelle 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"

L'astuce consistait à réaliser que la "session de cannelle" est trop longue pour que pgrep puisse trouver:

$ 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 car mon grep est alias

$ alias grep
alias grep='grep -n --color=always'
0
John Frankland

Tout ce dont vous avez besoin est X_user et X_userid. Remplacez les deux dans la commande ci-dessous.

Solution avec systemd

/etc/systemd/system/opreminder.service # fichier de service

[Unit]
Descrption=some service to run

[Service]
User=[X_user]
ExecStart=/home/jchester/bin/opreminder.sh


/etc/systemd/system/opreminder.timer #timer fichier

[Unit]
Description=Some desc


[Timer]
OnCalendar=0,15,30,45 12-23 * * 3 

[Install]
WantedBy=list.timer.target

/home/jchester/bin/opreminder.sh #Le script

#!/usr/bin/env bash

Sudo -u [X_user] DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/[X_userid]/bus notify-send 'Hello world!' 'This is an example notification.'

Pas besoin d'utiliser Sudo -u si le fichier de service est déjà défini avec l'utilisateur prévu

Source: https://wiki.archlinux.org/index.php/Desktop_notifications#Usage_in_programming

0
Bruno

J'utilise i3 sur Ubuntu 18.04. Ma façon de résoudre ceci est:

* * * * * XDG_RUNTIME_DIR=/run/user/$(id -u) notify-send Hey "this is dog!"

0
Mr. Goferito

Problème provoqué par l'appel de python3 dans la crontab avec UTF-8 locale.

TL; DR: appel de préfixe dans crontab w/locale comme dans:

*/5 * * * * LC_ALL=en_US.utf-8 LANG=en_US.utf-8 ~/.local/bin/watson-notify

Voir aussi click and python :

Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3/dist-packages/watson/__main__.py", line 6, in <module>
    cli.cli()
  File "/usr/lib/python3/dist-packages/click/core.py", line 759, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/click/core.py", line 693, in main
    _verify_python3_env()
  File "/usr/lib/python3/dist-packages/click/_unicodefun.py", line 123, in _verify_python3_env
    'for mitigation steps.' + extra)
RuntimeError: Click will abort further execution because Python 3 was configured to use ASCII as encoding for the environment.  Consult http://click.pocoo.org/python3/ for mitigation steps.

This system supports the C.UTF-8 locale which is recommended.
You might be able to resolve your issue by exporting the
following environment variables:

    export LC_ALL=C.UTF-8
    export LANG=C.UTF-8
0
Gen.Stack