通知发送在 crontab 中不起作用

use*_*335 58 cron 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
Run Code Online (Sandbox Code Playgroud)

这是我在 crontab 中写的

0,15,30,45 12-23 * * 3   /home/jchester/bin/opreminder.sh
Run Code Online (Sandbox Code Playgroud)

krl*_*mlr 43

13.04 上的情况似乎有所不同,至少在 Gnome Shell 中是这样。

首先,这是env从 userzzyxy的(不是 root 的)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
Run Code Online (Sandbox Code Playgroud)

根据DahitiF在 ubuntuforums.org 上的评论,为了开始notify-send工作,似乎有必要设置DBUS_SESSION_BUS_ADDRESS环境变量。只需在您的实际工作描述中添加以下内容:

eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";
Run Code Online (Sandbox Code Playgroud)

似乎没有必要设置DISPLAY.

  • 谢谢,这最终对我有用。在 Xubuntu 上,您必须将 `gnome-session` 更改为 `xfce4-session`。 (5认同)
  • 使用 `echo $DESKTOP_SESSION` 找出你的会话名称,我的是 `plasma` 因为我使用的是 Kubuntu。 (4认同)

Mar*_*ger 29

notify-send由 cron 启动时,Command不会在屏幕上显示消息。只需在脚本顶部添加目标显示,例如:

export DISPLAY=:0
Run Code Online (Sandbox Code Playgroud)

  • 这个。并在终端中使用 `echo $DISPLAY` 来确保你的显示确实是 `:0`(通常是,但并非总是如此)。 (3认同)

Mee*_*org 23

命令需要引用它们的位置。所以notify-send需要是/usr/bin/notify-send

所有命令都需要有完整的路径。

使用whereis notify-send命令查看您的命令“存在”的位置

  • 至少在我的系统上,即使对于 cron 作业,`notify-send` 也在`PATH` 上。请参阅下面的 [我的回答](http://askubuntu.com/a/346580/30266)。 (9认同)
  • 这不是答案。当然,如果无法找到可执行文件,它就不会运行,但是: 1. notify-send 在 PATH 上,所以它会被定位 2. 即使它不在 PATH 上,并且您指定了完整路径,它仍然会不起作用,因为实际上必须为通知发送设置 DBUS_SESSION_BUS_ADDRESS。正确答案来自kmir。 (5认同)
  • 这不是问题。问题是cron脚本不在用户会话下运行,对用户登录会话的环境没有概念。由于 notify-send 需要连接到 dbus 会话总线才能发送通知,因此当它没有连接到正确的会话总线时,从哪个路径调用二进制文件并不重要。 (4认同)
  • 这是否包括 cat、wget、if、let、grep、echo 等? (2认同)
  • 它不是 Ubuntu 17.04 的解决方案。请参阅 https://askubuntu.com/a/472769/413683 和 https://askubuntu.com/a/834479/413683。 (2认同)

nma*_*max 7

至少对于 Ubuntu 14.04,klrmr 上面的回答是正确的答案。似乎没有必要在 $PATH 中设置 DISPLAY 或阐明通知发送的完整路径或其他任何东西。

下面是当笔记本电脑的电池状态变得太低时我用来关闭虚拟机的 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
Run Code Online (Sandbox Code Playgroud)


Mr.*_*ito 6

我在 Ubuntu 18.04 和 20.04 上使用 i3。我解决这个问题的方法是:

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

  • 这对我有用,在我的脚本文件顶部添加了 `export` 行。`export XDG_RUNTIME_DIR=/run/user/$(id -u)` (3认同)
  • 这在 Ubuntu 20.04.2 LTS 上也适用于我。 (3认同)

小智 5

在我的 ubuntu 16.04 的情况下,需要任何显式路径,我只需添加即可解决问题

显示=:0

在 crontab 的第一行,在调用通知发送之前。