首页 > 解决方案 > 从鱼脚本执行通知发送作为cronjob

问题描述

我正在尝试将鱼脚本中的 notify-send 作为 cronjob 调用。即使脚本被 cron 调用,通知也不会在我的显示器上弹出。我不确定它在哪里失败,是否正在执行 notify-send,是否是 shell 问题或其他问题。在终端中执行脚本会产生预期的(即弹出窗口)结果

crontab -e -u $USER

  SHELL=/bin/fish

  * * * * * memcheck >> /tmp/cron.memcheck.log

runningtail --follow /tmp/cron.memcheck.log表明正在调用该脚本,因为它正在将调试输出回显到日志文件中,但它尾随于 launch notify-send

这是我的(noobish)脚本:

# Defined in /home/mio/.config/fish/functions/memcheck.fish @ line 2
function memcheck
    set MEM_USED (free | string replace '3914132' '' | string match 'Mem: [ ]{1,}[0-9]{1,}' --regex | string match '\d$
    #echo $MEM_USED
    set MEM_CAP 3914132
    set MEM_FREE (math $MEM_CAP - $MEM_USED)
    echo $MEM_FREE
    if test $MEM_FREE -lt 8700700
        echo "WARNING: memory usage out of control. 21:10"
        set DISPLAY :0.0
        echo $DISPLAY
        echo $USER
        /usr/bin/notify-send "Memory Usage" $MEM_FREE --urgency=critical
    end
end

我读过在某些情况下notify-send找不到显示和设置$DISPLAY可能:0.0会起作用。如果我echo $DISPLAY在我的终端我得到:0.0. 还呼应了$USER我的用户名,这是我预期的,因为我运行cronjob -u mio -e并且没有/etc/crontab直接编辑。谢谢你的时间。

标签: shellcronfish

解决方案


如果我在终端中回显 $DISPLAY 我会得到:0.0

是的,但是您的 cronjob 不在您的终端中运行。

在 Unix 中,环境变量会在父进程启动时传递给它们的子进程。

终端内的鱼是该终端的子终端,它的 $DISPLAY 设置为联系 X。

但是您的 cronjobs 由您的 cron 守护程序运行,该守护程序通常是您的 init 进程的子进程,而该进程又没有任何父进程。所以它继承了init的环境。


在脚本中设置 $DISPLAY。这不是很漂亮(而且我不能说我喜欢让 cronjob 开始发送通知的方法),但它应该可以工作,至少如果你有一台 X 服务器的典型设置。

请注意,鱼在这种情况下完全无关紧要 - 无论您选择什么作为外壳,它都会发生。

一些看似合理的替代方案(尽管我还没有深入研究它们):

  • watch在终端中或通过 DE 的自动启动机制运行作业。这只是每 X 秒重新运行一次,但是有$DISPLAY
  • 使用 systemd 的计时器,特别是作为用户。有一个命令可以将环境变量“上传”到 systemd,因此它可以在计时器中使用它。

推荐阅读