一年多前,我编写了一个通知应用程序。(在 Ubuntu 16.04.7 上)它使用 paplay 播放一些音频,然后打开一个带有通知文本的 yad 窗口。这可以从命令行或 cron 运行。最近我安装了 Ubuntu 20.04.3,发现从命令行运行仍然有效,但从 cron 运行无效。我的主目录下有一个 bin 目录,其中保存着脚本(remind.sh)。精简版的 reminder.sh 如下。请注意,当我从 cron 运行时,我没有收到脚本已运行的音频指示,但 trace.txt 文件会更新,并且 yad 会生成一个窗口。
#!/bin/bash
# reminder script called from either
# 1. cron or
# 2. directly from shell to pop-up or
# 3. gidday.sh
# produces a 'yad' window with a picture and message in it.
/usr/bin/paplay /home/gary/sounds/marimba.ogg
# trace the run
d=`date`
echo "done -- "$d >> trace.txt
# now put out the window
#
#/usr/bin/yad --borders=50 --scroll --image=/home/gary/Pictures/shrunk-pictures/${ar[$t]} --title="${ar[$t]}" --text-align=center --mouse --width=800 --height=400 --text='<span font="20">'"$txt"'</span>' 2>/dev/null
抱歉,我应该在原帖中提供以下内容。crontab 中触发 reminder1.sh 脚本的行是:
36 13 30 aug * export DISPLAY=:0 && export MESSG="get movies from lib" && /home/gary/bin/remind1.sh
正如我之前所说,这一切在 Ubuntu 16.04 中运行良好。但它仍然无法解释为什么 paplay 命令无法运行,而(未注释的)yad 命令却可以运行。
答案1
通过 运行的作业cron
或systemd
启动脚本不会在与桌面相同的运行时环境中运行。systemd
启动脚本以 运行root
。您的任何PATH
更改或其他环境变量设置~/.bashrc
都不会自动传播到您的cron
作业。例如,没有$DISPLAY
,因此 GUI 程序需要特殊处理(阅读man xhost
)。
cron
人们可以在crontab
文件 Read中为所有作业设置环境变量man 5 crontab
。
echo "=== id ===";id;echo "=== set ===";set;echo "=== env ===";env | sort;echo "=== alias ===";alias
查看每个环境中的结果 。
由于command
该行的一部分crontab
默认由 解释/bin/sh
,其语法比 更简单/bin/bash
,因此我建议command
调用一个bash
脚本(可执行、已安装、以 开头#!/bin/bash
)来设置环境,然后调用所需的程序。
答案2
您应该检查输出
env|grep -i runt
对我来说它是 XDG_RUNTIME_DIR=/run/user/1000
然后将它放入 crontab 作业的环境中,如下所示:
* * * * * export XDG_RUNTIME_DIR=/run/user/1000 && paplay sound.wav