crontab 排错事项通常有三点:
1. 置顶 SHELL=/bin/bash ,因为默认 shell 可能不支持你放在 crontab 的语法。
2. 命令和 shell 脚本加上 echo yyy >> /tmp/xxx.log (别忘了 >> 和 > 的区别) 或 touch /tmp/yyy.log (别忘了删除), 来确认你要执行的 crontab 命令或 shell 脚本有运行至重点部分。
3. 环境变量。
新手最意想不到的排错正是第三种,环境变量。在交互模式有环境变量促使某些命令能运行, crontab 默认没有给以足够的环境变量。
让我说说如何在 xubuntu 利用 crontab 换背景图。
终端输入命令
crontab -e
(如果是问 editor, 就选 vim.tiny),然后敲 i 进入 insert mode, 输入:SHELL=/bin/bash
* * * * * (PID=$(pgrep xfce4-session); export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-); xfconf-query --channel xfce4-desktop --property /backdrop/screen0/monitor0/workspace0/last-image --set /home/xubuntu/Pictures/1.jpg)
* * * * * (sleep 5; PID=$(pgrep xfce4-session); export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-); xfconf-query --channel xfce4-desktop --property /backdrop/screen0/monitor0/workspace0/last-image --set /home/xubuntu/Pictures/2.jpg)
然后 Esc,然后 :wq 储存出去。然后每1分钟的第一秒会换背景图成 /home/xubuntu/Pictures/1.jpg,然后等 5 秒会变成 /home/xubuntu/Pictures/2.jpg,然后等多 50 秒又变回去 1.jpg, ... 周而复始。
上面的
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-);
用途是什么 ?用途是换背景图需要定义
DBUS_SESSION_BUS_ADDRESS
这个环境变量。在终端交互模式输入
env
就能知道当前的变量,再和 crontab 的 env > /tmp/env.log
做个比较,就能知晓 crontab 默认的环境变量是很少的。如何知晓换背景图需要 DBUS_SESSION_BUS_ADDRESS 这个关键的环境变量 ? 你可以用我独创的姿势:
a.
declare -p > /tmp/d.sh
env > /tmp/d.sh 会卸掉引号所以不适合直接用, 所以才选择 declare -p > /tmp/d.sh。内容里的 declare -x 恰好就是 export 。
b. 在 /tmp/test.sh 输入 (eog 程序拿来看图, 只是例子):
. /tmp/d.sh
eog /home/xiaobai/Pictures/1.jpg
c. 最后不停测试如下。 如果成功显示图片,就删除 /tmp/d.sh 一半的内容; 反之则 undo 再删除另一半, 或一半的一半:
env -i bash /tmp/test.sh
原理是 env -i 去除全部环境变量,然后 source (点号) 那新的环境变量让脚本使用。d. 最后就能快速锁定出最关键的环境变量, 可以是多个环境变量, 比如 eog 需要 DBUS_SESSION_BUS_ADDRESS 和 DISPLAY。
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
declare -x DISPLAY=":0"
缺少 DBUS_SESSION_BUS_ADDRESS 并非看不见图片,而是延迟,所以环境变量缺少的后果可能并非那么直观。
最后,crontab 的默认环境变量可能会影响,且 env -i 并非完全没有环境变量,你必须考量这种可能性。
No comments:
Post a Comment