Utilizzo di notifica-invio con cron


32

Sto usando Arch Linux con KDE / Awesome WM. Sto cercando di mettermi notify-sendal lavoro cron.

Ho provato a impostare DISPLAY/ XAUTHORITYvariabili e in esecuzione notify-sendcon "sudo -u", il tutto senza risultati.

Sono in grado di chiamare in modo interattivo notifica-invio dalla sessione e ricevere notifiche.

FWIW, il cron job sta funzionando bene, cosa che ho verificato facendo eco ad un file temporaneo. È solo la "notifica-invio" che non funziona.

Codice:

[matrix@morpheus ~]$ crontab -l
* * * * *  /home/matrix/scripts/notify.sh

[matrix@morpheus ~]$ cat /home/matrix/scripts/notify.sh
#!/bin/bash
export DISPLAY=127.0.0.1:0.0
export XAUTHORITY=/home/matrix/.Xauthority
echo "testing cron" >/tmp/crontest
sudo -u matrix /usr/bin/notify-send "hello"
echo "now tested notify-send" >>/tmp/crontest

[matrix@morpheus ~]$ cat /tmp/crontest
testing cron
now tested notify-send

[matrix@morpheus ~]$ 

Come puoi vedere l'eco prima e dopo aver inviato notifica ha funzionato.
Inoltre ho provato a impostareDISPLAY=:0.0

AGGIORNAMENTO: ho cercato un po 'di più e ho scoperto che DBUS_SESSION_BUS_ADDRESS deve essere impostato. E dopo aver codificato questo utilizzando il valore che ho ottenuto dalla mia sessione interattiva, il piccolo messaggio "ciao" ha iniziato a comparire sullo schermo ogni minuto!

Ma il problema è che questa variabile non è permanente per quel post, quindi proverò la soluzione di pipe indicata qui suggerita.

[matrix@morpheus ~]$ cat scripts/notify.sh
#!/bin/bash
export DISPLAY=127.0.0.1:0.0
export XAUTHORITY=/home/matrix/.Xauthority
export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-BouFPQKgqg,guid=64b483d7678f2196e780849752e67d3c
echo "testing cron" >/tmp/crontest
/usr/bin/notify-send "hello"
echo "now tested notify-send" >>/tmp/crontest

Dal momento cronche non sembra supportare la notifica-invio (almeno non direttamente), esiste qualche altro sistema di notifica più cronamichevole che posso usare?


Questo dovrebbe funzionare per quanto posso vedere. Perché non aggiungi &>>/tmp/crontesta alla riga di invio notifica e vedi se vengono visualizzati notify-sendmessaggi di errore.
Graeme,

Per curiosità, hai provato la mia soluzione? Sembra molto più semplice e ha funzionato perfettamente sul mio Debian. Chiedo solo di sapere se Debian è specifico o no
terdon

@terdon Ho provato la tua soluzione (solo un test rapido) e sembra funzionare sul mio sistema Debian. Mi piacerebbe sapere se è generalmente applicabile poiché è davvero più semplice.
Marco,

@Marco Sono su LMDE (essenzialmente test Debian) e utilizzo Cinnamon come DE. Non posso dirti se funziona oltre quelli.
terdon

@Marco & terdon: ragazzi Ubuntu sono in grado di farlo: ubuntuforums.org/showthread.php?t=1727148
justsomeone

Risposte:


29

Devi impostare la DBUS_SESSION_BUS_ADDRESSvariabile. Di default cron non ha accesso alla variabile. Per porre rimedio a ciò, metti il ​​seguente script da qualche parte e chiamalo quando l'utente accede, ad esempio usando awesome e la run_oncefunzione menzionata sul wiki. Qualsiasi metodo lo farà, poiché non danneggia se la funzione viene chiamata più spesso del necessario.

#!/bin/sh

touch $HOME/.dbus/Xdbus
chmod 600 $HOME/.dbus/Xdbus
env | grep DBUS_SESSION_BUS_ADDRESS > $HOME/.dbus/Xdbus
echo 'export DBUS_SESSION_BUS_ADDRESS' >> $HOME/.dbus/Xdbus

exit 0

Questo crea un file contenente la variabile di evironment Dbus richiesta. Quindi nello script chiamato da cron importa la variabile acquistando lo script:

if [ -r "$HOME/.dbus/Xdbus" ]; then
  . "$HOME/.dbus/Xdbus"
fi

Ecco una risposta che utilizza lo stesso meccanismo.


1
Sono contento di vedere che ero quasi vicino alla soluzione. Grazie Marco, è pulito!
justsomeone,


Non sarebbe un rischio per la sicurezza? security.stackexchange.com/questions/71019/…
rubo77

@Gilles Come hai potuto farlo in una riga come hai menzionato in chat?
rubo77,

Ho provato tante altre risposte, escluso DBUS su Ubuntu 15.10 e niente ha funzionato. Quello è semplice e funziona perfettamente.
Bastian,

16

Devi impostare le variabili nello stesso crontab:

DISPLAY=:0.0
XAUTHORITY=/home/matrix/.Xauthority

# m h  dom mon dow   command 
* * * * *  /usr/bin/notify-send "hello"

Non sudonecessario, almeno non sul mio sistema.


Grazie per il tuo tempo. Questa sembra essere una soluzione semplice. Sfortunatamente, questo non ha funzionato per me,
justsomeone,

@justsomeone huh, OK, allora potrebbe dipendere dall'ambiente desktop.
terdon

Penso che questo abbia qualcosa a che fare con la distro o l'ambiente desktop. Per gli utenti Ubuntu, le soluzioni semplici sembrano funzionare bene da quello che ho visto nei forum online.
justsomeone,

@justsomeone Sono su Debian (LMDE) usando Cinnamon come DE. Potrebbe avere qualcosa a che fare con il modo in cui X viene avviato o con il sistema di notifiche utilizzato da DE, non lo so.
terdon

Confermato che funziona su Ubuntu 14.04 / 14.10. Con GNOME e Unity.
Jordon Bedwell,

8

Il modo più sicuro per ottenere le variabili ambientali relative alla sessione X è ottenerle dall'ambiente di un processo dell'utente che ha eseguito l'accesso a X. Ecco un adattamento dello script che utilizzo esattamente per lo stesso scopo (sebbene DBUS_SESSION_BUS_ADDRESS non lo faccia ' sembra essere un problema per me su Debian):

X=Xorg                   # works for the given X command
copy_envs="DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS"

tty=$(ps h -o tty -C $X | head -1)
[ -z "$tty" ] && exit 1

# calling who with LANG empty ensures a consistent date format
who_line=$(LANG= who -u | grep "^[^ ]\+[ ]\+$tty")

x_user=$(echo $who_line | cut -d ' ' -f 1)  # the user associated with the tty
pid=$(echo $who_line | cut -d ' ' -f 7)     # the user's logon process

for env_name in $copy_envs
do
  # if the variable is not set in the process environment, ensure it does not remain exported here
  unset "$env_name"

  # use the same line as is in the environ file to export the variable
  export "$(grep -az "^$env_name=" /proc/$pid/environ)" >/dev/null
done

sudo -u "$x_user" notify-send "hello"

Questo invia al messaggio il primo utente X che trova, sebbene sia possibile aggiungere un ciclo per inviarlo a tutti gli utenti.

Aggiornare

Sembra che gli aggiornamenti al formato utmp causino la whostampa di un display invece di un tty nella sua seconda colonna. Questo in realtà semplifica le cose, in precedenza ha stampato il display solo nel commento alla fine e ho deciso che non era sicuro fare affidamento sulla risposta originale. In questo caso, prova questo:

X=Xorg                   # works for the given X command
copy_envs="DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS"

# calling who with LANG empty ensures a consistent date format
who_line=$(LANG= who -u | awk '$2 ~ ":[0-9]"')

x_user=$(echo $who_line | cut -d ' ' -f 1)  # the user associated with the tty
pid=$(echo $who_line | cut -d ' ' -f 7)     # the user's logon process

for env_name in $copy_envs
do
  # if the variable is not set in the process environment, ensure it does not remain exported here
  unset "$env_name"

  # use the same line as is in the environ file to export the variable
  export "$(grep -az "^$env_name=" /proc/$pid/environ)" >/dev/null
done

sudo -u "$x_user" notify-send "hello"

Questo non funziona per me su Trusty perché non c'è tty stampato nel who_linecomando. L'output è simile me :0 2015-09-23 10:40 ? 17234.
blujay,

1
@blujay, aggiornato.
Graeme,

Grazie, funziona. Tuttavia, come ho pubblicato in una risposta separata, esiste una soluzione ancora più semplice.
Blujay,

@blujay sì, questo è stato un tentativo di risposta portatile. Non sono sicuro che questo sia davvero possibile, ma dovrebbe comunque funzionare nella maggior parte dei casi.
Graeme,

2

Questo one-liner ha funzionato per me a Manjaro con Cronie:

# Note: "1000" would be your user id, the output of... "id -u <username>" 
10 * * * * pj DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send 'Hello world!' 'This is an example notification.'

Senza il brutto DBUS_blah_blah non funziona affatto. Ho anche trovato journalctl -xb -u cronieutile. Non ho ancora familiarità con Cronie, ma ho creato il mio "crontab" come /etc/cron.d/mycronjobse non sono sicuro se quel nome file sia richiesto o se legga semplicemente tutto nella directory cron.d.

Ho trovato la soluzione qui https://wiki.archlinux.org/index.php/Desktop_notifications


2

Uso i3 su Ubuntu 18.04. Il mio modo di risolvere questo è:

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


1

Questo è sufficiente per far funzionare le notifiche per me in un cronjob su Ubuntu Trusty:

#!/bin/bash
export DISPLAY=$(who -u | awk  '/\s:[0-9]\s/ {print $2}')

Esporta semplicemente DISPLAYper l'utente su cui è in esecuzione cronjob. Funziona per me senza impostazione XAUTHORITYo DBUS_SESSION_BUS_ADDRESS.


1
Funziona anche su Ubuntu 16.04. In realtà ho cron che lancia uno script Perl, che system () è uno script bash, che avvia uno script Perl diverso, che esegue un sistema ("notification-send ..."). L'aggiunta del comando export allo script bash ha modificato l'ambiente per quello script, che l'ultimo script Perl ha poi ereditato e reso disponibile al sistema ("notification-send ..."). Buona scoperta blujay!
Tim

1

Per quelli su Linux che hanno dimestichezza con l'installazione di pacchetti Python, ho appena rilasciato un programma di notifica-invio-headless che funziona bene per me. Cerca /procil nome utente e le variabili di ambiente richieste, quindi viene eseguito notify-sendcon queste variabili (verrà utilizzato sudoper passare all'utente richiesto, se necessario).


1

Puoi anche creare uno script:

#!/usr/bin/env bash
runuser -l [yourusername] -c 'DISPLAY=:0 notify-send "hey there user"'

Quindi eseguirlo con sudo. Tuttavia, poiché crontab -eesegue tutti i comandi con l'utente che lo ha creato, quanto segue dovrebbe essere sufficiente quando chiamato senza sudo:

#!/usr/bin/env bash
DISPLAY=:0 notify-send "hey there user"

Almeno lo fa per me. Tutto sembra dipendere dalla configurazione dell'ambiente.


0

Uso questo script in cron per pubblicare MPD che ora gioca su Twitter ogni ora

#!/bin/bash
export DISPLAY=":0.0"
msg=$(mpc current -h 192.168.1.33)
twitter set "#MPD Server nowplaying $msg :  http://cirrus.turtil.net:9001"
#ttytter -status="#MPD Server nowplaying $msg. http://cirrus.turtil.net:9001"

exit 

script simile usando Notify-Send

#!/bin/bash
export DISPLAY=":0.0"
notify-send -i ~/.icons/48arch.png 'OS- Archlinux x86_64 : DWM Window Manager' 'Installed on Sun Apr 21 2013 at 18:17:22' 
exit

potresti riscontrare problemi poiché KDE utilizza il proprio IIRC notification-deamon.


0

Per quello che vale....

Ho dovuto usare TUTTO quanto segue su Debian Jessie per farlo funzionare ...

export DISPLAY=:0.0
export HOME=/home/$user
source "$HOME/.dbus/session-bus/*-0"

Tralasciare uno di questi ha fatto smettere di funzionare.


L'ultima riga non farà nulla come scritto qui, perché non ci sarà alcun file chiamato letteralmente *-0nella tua session-busdirectory. Avresti potuto significare source "$HOME"/.dbus/session-bus/*-0.
roaima,

0

Usando sudo:

sudo -u $currentxuser notify-send $message

Mancia :

Con questo comando possiamo ottenere l'utente x corrente

ps auxw | grep -i screen | grep -v grep | cut -f 1 -d ' '

Inoltre...

currentxuser=$(ps auxw | grep -i screen | grep -v grep | cut -f 1 -d ' ')
echo $currentxuser

Buono a sapersi :

Cron in esecuzione su root non ha accesso a x quindi non verranno visualizzati tutti i comandi gui, una semplice soluzione è aggiungere root a utente x autorizzato per l'utente x corrente con questo comando

dalla shell utente x

xhost local:root

o

sudo -u $currentxuser xhost local:root

-1

Ecco uno script meno complesso di quello che Graeme ha fornito. La sua sceneggiatura non ha funzionato per me, $who_lineera sempre vuota. La mia sceneggiatura non perde molto tempo a trovare un processo. Invece, prova solo tutto e seleziona l'ultimo valore utile trovato. Sto eseguendo xubuntu 14.04 e ho alcuni container lxc che probabilmente confondono questo tipo di script.

env="$(
  ps -C init -o uid,pid | while read u p; do
    [ "$u" = "`id -u`" ] || continue
    grep -az '^DBUS_SESSION_BUS_ADDRESS=' /proc/$p/environ | xargs -0
  done | tail -1
)"

export "$env"

notify-send "test"

Questo non funziona per me su Trusty perché l'ambiente del processo Xorg non ha DBUS_SESSION_BUS_ADDRESS. Posso ottenerlo dalle mie shell, ma non dal processo Xorg.
blujay,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.