Notify-send crontab'dan çalışmıyor


44

Okuduğum yeni bir manga bölümü olduğunda beni bilgilendirmesi gereken bir senaryo yazdım. Bunu yapmak için notify-send komutunu kullandım. Program terminalde çalıştırmaya çalıştığımda çalışıyor. Bildirim gösteriliyor. Ancak, bunu crontab'a yerleştirdiğimde bildirim görünmüyor. Benim için bir dosya oluşturduğumdan beri programın çalıştığından eminim. Dosya oluşturuldu, ancak bildirim görünmedi.

İşte betiğim

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

Ve işte crontab'ımda yazdıklarım

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

Sadece bir hatırlatıcı olarak, crontab'daki tüm komutların, kök olarak çalıştığı gibi yollarının önünde olması gerekir. Crontab'a komut dosyası ve satır eklemek yardımcı olur, aksi takdirde sadece sorununuzu tahmin ediyoruz
Meer Borg

Evet üzgünüm. Daha yeni yaptım.
kullanici158335

Bu kötü bir fikir. Bildirimler "GUI", cron ise "konsol" şeklindedir. Lib-notify'ın mesajı görüntülemenin bir yolunu bulabileceğine dair hiçbir garanti yoktur. Bunun yerine, stdout'a veri göndermeyi düşünmelisiniz ve cron'un mesajlaşma işleminin bilgiyi göndermeye özen göstermesine izin vermelisiniz. Normalde bir e-posta gönderilir.
coteyr,

2
Yanı örneğin yardımcı olabilir EKRAN değişken yukarı ayarlama Bazı durumlarda: export DISPLAY=:0.
Glutanimate

1
Çünkü 16.04, bu benim için çalıştı */1 * * * * eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";/usr/bin/notify-send -i appointment -c "im" "Keep Working"
KrIsHnA

Yanıtlar:


18

Komutların yerlerini referans almaları gerekir. Öyle notify-sendolması gerekiyor/usr/bin/notify-send

Tüm komutların tam yoluna sahip olmaları gerekir.

whereis notify-sendKomutlarınızın "nerede yaşadığını" görmek için komutu kullanın


2
Bu grep, echo, eğer izin, eğer, kedi, wget içerir mi?
kullanici158335

7
En azından sistemimde bir cron işi notify-sendiçin PATHbile var. Bkz cevabımı altında.
krlmlr 17:13

2
Ubuntu 17.04 için bir çözüm değildir. Bkz askubuntu.com/a/472769/413683 ve askubuntu.com/a/834479/413683 yerine.
Mateusz Piotrowski

2
Sorun bu değil. Sorun cron komut dosyalarının kullanıcı oturumu altında çalışmaması ve kullanıcının oturum açma oturumunun ortamı hakkında hiçbir fikrinin olmamasıdır. Notify-send, bildirimi göndermek için bir dbus oturum veriyoluna bağlanmayı gerektirdiğinden, doğru oturum veriyoluna bağlanmadığında, ikili sistemin hangi yoldan çağrıldığı önemli değildir.
dobey

2
Cevap bu değil. Çalıştırılabilir bulunamıyorsa, çalıştırılmayacağından emin olun, ANCAK: 1. notify-send PATH üzerinde, bu nedenle de bulunacak 2. PATH üzerinde olmasa bile, tam yolunu siz belirtin çalışmaz, çünkü aslında DBUS_SESSION_BUS_ADDRESS notify-send için ayarlanmış olmalıdır. Doğru cevap kmir'den.
Kris Jace,

31

13.04'te, en azından Gnome Shell'de işler farklı görünüyor.

Birincisi, bu, envkullanıcının zzyxy(root'un değil) cron işinden çalıştırıldığında çıkan şeydir :

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

Almak için notify-sendişe, o ayarlamak için gerekli gibi görünüyor DBUS_SESSION_BUS_ADDRESSgereği, çevre değişkeni DahitiF yorumuyla ubuntuforums.org üzerinde. Aşağıdakileri gerçek iş tanımınıza göre hazırlayın:

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

Ayarlanması gerekli görünmüyor DISPLAY.


4
Sağol, sonunda benim için işe yaradı. Xubuntu üzerinde, değişime gerek gnome-sessioniçin xfce4-session.
shrx

Bu 14.04 için çalışacak tek cevap ve kabul edilenlerin açık bir ipucu.
Wtower

1
Hiç vardı gnome-sessionve kullanılmış gnome-shellyerine (aynı zamanda orada dikkatli bir gnome-shell-calendar-servernedenle pgrep2 pids alacak). Ayrıca DISPLAY=:02 tane fiziksel ekran kullanıyorum ve tanımlanmadığı için de ihtiyacım vardı . Teşekkürler!
soyuka

(++ CB gibi) içinde takas Openbox kullanıyorsanız openboxiçin gnome-session.
ACK_stoverflow,

BU doğru cevaptır ve kabul edilen cevap doğru değildir, hatta gerekli olmayan DISPLAY değişkeninden bahseder ya da sorunu çözmez.
Kris Jace,

24

Komut notify-sendcron tarafından başlatıldığında ekranınızdaki mesajı göstermez. Sadece betiğinizin üstüne hedef görüntüleme ekleyin, örneğin:

export DISPLAY=:0

Bu benim de 14.10'da yapmam gereken şeydi. Aksi takdirde bu hatayı gdk_mir_display_open Failed to connect to Mir: Failed to connect to server socket: No such file or directory Option parsing failed: Cannot open display:
alırdım

1
Bu. Ve kullanım echo $DISPLAYterminal içinde görüntülü gerçekten olduğundan emin olmak için :0(ki bu genelde, ama her zaman değil).
Mark

Sadece bu benim için çalıştı, Linux Nane kullanıyorum
Harendra Singh

5

En azından Ubuntu 14.04 için yukarıdaki klrmr'ın cevabı doğru cevaptır. $ PATH içinde DISPLAY'i ayarlamak veya bildirmek-göndermek için tam yollar veya normalde başka bir şey ifade etmek gerekli görünmüyor.

Aşağıda bir dizüstü bilgisayarın pil durumu çok düşük olduğunda sanal bir makineyi kapatmak için kullandığım bir cron betiği verilmiştir. Yukarıdaki klrmr'nin cevabında DBUS_SESSION_BUS_ADDRESS ayar satırı, nihayetinde uyarıların doğru çalışmasını sağlayan değişikliktir.

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

Bu benim için de mükemmel sonuç veren çözümdü, crontab'dan çalıştığım senaryomuza "eval ..." satırını daha yeni ekledim - şimdi mükemmel çalışıyor
Mtl Dev

2

Ubuntu 16.04 ile ilgili durumumda herhangi bir açık yol gerekliydi, sorunu sadece ekleyerek çözdüm

EKRAN = 0

crontab'ın ilk satırlarında, çağrı yapmadan önce notify-send.


16.04'te çalışması için gereken tek şey bu.
Jonathan Landrum

1

İlk suçlu crontab dosyanızdır, ayrıca betiğin çalıştırılacağı kullanıcı adını da belirtmelisiniz, daha iyi root olarak saklayın

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

ve sonra komut dosyasında GUI kullanıcısının kullanıcı_adı'nı kullanmalı ve komutu GUI'ye sahip bir kullanıcı olarak yürütmek için "sudo veya su" ile notify-göndermeye hazırlamalısınız

örnek :

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

veya

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

gnome_user_nameGUI oturumunu başlatan kullanıcının kullanıcı adı nerede ? Giriş yapan sizsiniz ve dinamik bir seçim yapmak istiyorsanız,

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

örnek :

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

veya

sudo -u $GNOME_USER notify-send "summary" "body"

1
Kullanıcı adınız X karakterden daha uzun olduğunda, kullanıcı adınızın kısaltıldığı görüşündeyim: Örneğin, kullanıcı adım gösteriliyor oniltonmaciel, ancak $GNOME_USERgösteriliyor onilton+(çalışmıyor)
Onilton Maciel

daha iyi komutla
düzelttim

1

İkilinin dbus adresini alma şekli son zamanlarda değişmiş görünüyor. "Notify-send 0.7.6" olan Ubuntu 15.04'te (Vivid Vervet) aşağıdaki iki değişkene ihtiyaç vardır:

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

'Krlmlr' ifadesi iyi değerlendirir ve doğru adresi belirler, ancak iletişim bir cron işinden açılmaz.


0

Eğer crontab'daki betiğiniz root olarak çalışıyorsa, yukarıdaki cevaplar muhtemelen işe yaramayacaktır. 16.04'te benim için iyi çalışan bu işlevi deneyin:

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 
}

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


0

dbus-sessionSürece güvenmek daha iyi DBUS_SESSION_BUS_ADDRESS, mevcut olan tüm sistemler için çalışıyor olmalıdır .

Bir komut dosyası oluşturun:

#!/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!"

Çalıştırılabilir yap:

$ chmod +x ~/notify.sh

Crontab'a ekle:

* * * * * $HOME/notify.sh

0

Bu ubuntu 15.10 üzerinde çalışmak için sonsuza dek sürdü, kullanıcıları normal env vars almak için bir kaynak eklemek zorunda kaldı. ekranım: 1 nedense de. GNOME oturumunu kullanmak ilk önce DBUS_SESSION_BUS_ADDRESS araması için bir sonuç verir.

# 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

Aşağıdaki tarifi kullanarak Ubuntu 15.10'daki tarçın masaüstüyle çalışmamı sağladım:

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"

İşin püf noktası, “tarçın seansının” pgrep'in bulamayacağı kadar uzun olduğunu fark etmekti:

$ 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

Benim grep takma ad çünkü \ grep kullanmak zorunda kaldı

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

0

İ3'ü Ubuntu 18.04'da kullanıyorum. Bunu çözmenin yolu şudur:

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


0

Yerel ayar python3ile crontab'ı çağırmanın neden olduğu sorun UTF-8.

TL; DR: crontab’da aşağıdaki gibi crontab’da önek çağrısı:

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

Ayrıca bakınız ve python3 :

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

Libnotify kullanan tüm crontab betiği için şunu kullandım:

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

notify_user # and do other stuff

Kök modunda cron kullansam bile işe yarıyor.


0

Tek ihtiyacınız olan X_user ve X_userid. Komuttaki her ikisini de aşağıdaki şekilde değiştirin.

Systemd ile çözüm

/etc/systemd/system/opreminder.service # Servis dosyası

[Unit]
Descrption=some service to run

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


/etc/systemd/system/opreminder.timer #timer dosyası

[Unit]
Description=Some desc


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

[Install]
WantedBy=list.timer.target

/home/jchester/bin/opreminder.sh # Senaryo

#!/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.'

Servis dosyası zaten istenen kullanıcı ile ayarlanmışsa, sudo -u kullanmanıza gerek yoktur.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.