私が読んでいる漫画の新しい章があるときに通知するスクリプトを作成しました。これを行うには、コマンド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
コマンドはその場所を参照する必要があります。 notify-send
は/usr/bin/notify-send
である必要があります
すべてのコマンドには完全なパスが必要です。
whereis notify-send
コマンドを使用して、コマンドの「ライブ」の場所を確認します
少なくとも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
を設定する必要はないようです。
コマンドnotify-send
は、cronで起動したときに画面にメッセージを表示しません。スクリプトの上部にターゲット表示を追加するだけです。例えば:
export DISPLAY=:0
少なくとも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
私の場合、ubuntu 16.04では明示的なパスが必要でしたが、追加するだけで問題を解決します
DISPLAY =:0
notify-sendを呼び出す前に、crontabの最初の行で。
最初の原因は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"
バイナリがdbusアドレスを取得する方法は、最近変更されたようです。 「notify-send 0.7.6」を使用するUbuntu 15.04(Vivid Vervet)では、次の2つの変数が必要です。
export HOME=/home/$notify_user
export DISPLAY=:0.0
'krlmlr'によるステートメントは正常に評価され、正しいアドレスを設定しますが、ダイアログはcronジョブからポップアップしません。
Libnotifyを使用するすべてのcrontabスクリプトについて、これを使用します。
notify_user() {
local user=$(whoami)
notify-send -u normal -t 4000 "System Backup" "Starting backup"
}
notify_user # and do other stuff
ルートモードでcronを使用しても動作します。
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
}
これは、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)"
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
次のレシピを使用して、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'
必要なのはX_userとX_useridだけです。以下のコマンドで両方を置き換えます。
/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
Ubuntu 18.04でi3を使用しています。これを解決する私の方法は次のとおりです。
* * * * * XDG_RUNTIME_DIR=/run/user/$(id -u) notify-send Hey "this is dog!"
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