Notify-send在crontab中不起作用
我制作了一个脚本,当我正在阅读漫画的新章节时,它应该通知我。 我使用命令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
命令查看命令“活动”的位置
事情似乎在13.04有所不同,至少在Gnome Shell。
首先,这是从用户zzyxy
(而不是root的)cron作业运行时的env
打印:
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
工作,根据DahitiF对ubuntuforums.org 的评论 ,似乎有必要设置DBUS_SESSION_BUS_ADDRESS
环境变量。 只需在您的实际工作描述中添加以下内容:
eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";
似乎没有必要设置DISPLAY
。
当cron启动时,命令notify-send
不会在屏幕上显示消息。 只需在脚本顶部添加目标显示,例如:
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并将其作为notify-send的前缀添加“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)上,需要以下两个变量:
export HOME=/home/$notify_user export DISPLAY=:0.0
‘krlmlr’的语句评估正常并设置正确的地址,但对话框不会从cron作业弹出。
如果crontab中的脚本以root用户身份运行,则上述答案可能无效。 试试这个function,16.04对我来说很好用:
notify_all() { local title=$1 local msg=$2 who | awk '{print $1, $NF}' | tr -d "()" | while read ud; 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 )
最好依赖于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上工作,必须添加一个源来获得用户正常的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)"
我刚刚在Ubuntu 15.10上使用肉桂桌面,使用以下配方:
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'