web-dev-qa-db-ja.com

crontabからNotify-Sendが機能しない

私が読んでいる漫画の新しい章があるときに通知するスクリプトを作成しました。これを行うには、コマンドnotify-sendを使用しました。このプログラムは、ターミナルで実行しようとすると機能します。通知が表示されています。ただし、これをcrontabに配置すると、通知が表示されません。私はファイルを作成するためにプログラムを作成したので、プログラムが実行されていると確信しています。ファイルは作成されましたが、通知は表示されませんでした。

これが私のスクリプトです

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

そして、これが私がcrontabに書いたものです

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

コマンドはその場所を参照する必要があります。 notify-send/usr/bin/notify-sendである必要があります

すべてのコマンドには完全なパスが必要です。

whereis notify-sendコマンドを使用して、コマンドの「ライブ」の場所を確認します

18
Meer Borg

少なくともGnome Shellでは、13.04では状況が異なっているようです。

まず、これはenvがユーザーzzyxyの(ルートではなく)cronジョブから実行したときに出力されるものです。

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

notify-sendを機能させるには、ubuntuforums.orgの DahitiFのコメント に従って、DBUS_SESSION_BUS_ADDRESS環境変数を設定する必要があるようです。実際の仕事の説明に次を追加してください:

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

DISPLAYを設定する必要はないようです。

31
krlmlr

コマンドnotify-sendは、cronで起動したときに画面にメッセージを表示しません。スクリプトの上部にターゲット表示を追加するだけです。例えば:

export DISPLAY=:0
24
Martin Höger

少なくともUbuntu 14.04の場合、 klrmrの上記の応答 が正しい答えです。 $ PATHでDISPLAYを設定したり、notify-sendのフルパスを明示したり、その他の通常のことを行う必要はないようです。

以下は、ラップトップのバッテリー状態が低くなりすぎたときに仮想マシンをシャットダウンするために使用しているcronスクリプトです。上記のklrmrの応答でDBUS_SESSION_BUS_ADDRESSを設定する行は、最終的に警告が正しく機能するようになった変更です。

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

私の場合、ubuntu 16.04では明示的なパスが必要でしたが、追加するだけで問題を解決します

DISPLAY =:0

notify-sendを呼び出す前に、crontabの最初の行で。

2
Raul R.

最初の原因はcrontabファイルです。また、スクリプトを実行する必要があるユーザー名を記載する必要があります。これは、rootとして保持することをお勧めします

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

そして、スクリプト内でGUIユーザーのuser_nameを使用し、「Sudoまたはsu」で通知送信するためにそれを先頭に追加して、GUIを所有するユーザーとしてコマンドを実行する必要があります。

例:

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

または

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

ここで、gnome_user_nameは、GUIセッションを開始したユーザーのユーザー名です。ログインしたのはあなたであり、動的な選択にしたい場合は、次から取得できます。

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

例:

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

または

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

バイナリがdbusアドレスを取得する方法は、最近変更されたようです。 「notify-send 0.7.6」を使用するUbuntu 15.04(Vivid Vervet)では、次の2つの変数が必要です。

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

'krlmlr'によるステートメントは正常に評価され、正しいアドレスを設定しますが、ダイアログはcronジョブからポップアップしません。

1
tanza

Libnotifyを使用するすべてのcrontabスクリプトについて、これを使用します。

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

notify_user # and do other stuff

ルートモードでcronを使用しても動作します。

0
azzamsa

Crontab内のスクリプトがrootとして実行されている場合、上記の回答はおそらく機能しません。この機能を試してください。これは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 
}

(ソース: https://unix.stackexchange.com/a/344377/7286

0
mivk

これは、ubuntu 15.10で作業を行うのに永遠にかかりました。ユーザーに通常のenv変数を取得するためのソースを追加する必要がありました。私のディスプレイも何らかの理由で:1でした。 gnome-sessionを使用すると、DBUS_SESSION_BUS_ADDRESSルックアップのpidが最初に表示されます。

# 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

dbus-sessionプロセスに依存する方が、DBUS_SESSION_BUS_ADDRESSが存在するすべてのシステムで実行する必要があります。

スクリプトを作成します。

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

実行可能にする:

$ chmod +x ~/notify.sh

Crontabに追加します。

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

次のレシピを使用して、Ubuntu 15.10のcinnamonデスクトップで動作するようになりました。

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"

トリックは、pgrepが見つけるには「シナモンセッション」が長すぎることを認識することでした。

$ 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

私のgrepのエイリアスは\ grepでもあるため、

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

必要なのはX_userとX_useridだけです。以下のコマンドで両方を置き換えます。

Systemdによるソリューション

/etc/systemd/system/opreminder.service#サービスファイル

[Unit]
Descrption=some service to run

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


/etc/systemd/system/opreminder.timer #timerファイル

[Unit]
Description=Some desc


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

[Install]
WantedBy=list.timer.target

/home/jchester/bin/opreminder.sh#スクリプト

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

サービスファイルが目的のユーザーで既に設定されている場合、Sudo -uを使用する必要はありません。

ソース: https://wiki.archlinux.org/index.php/Desktop_notifications#Usage_in_programming

0
Bruno

Ubuntu 18.04でi3を使用しています。これを解決する私の方法は次のとおりです。

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

0
Mr. Goferito

python3ロケールでcrontabのUTF-8を呼び出したために発生した問題。

TL; DR:crontab w/localeのプレフィックス呼び出し:

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

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