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
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".
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
.
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
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
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.
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"
où 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"
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.
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.
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 )
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)"
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
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'
Tout ce dont vous avez besoin est X_user et X_userid. Remplacez les deux dans la commande ci-dessous.
/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
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!"
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