【发布时间】:2016-04-16 12:54:46
【问题描述】:
我正在尝试从 cron 运行 bash 脚本,但似乎没有任何效果。
脚本:
#!/bin/sh
printf '%s' $(date) '_END' >> battery_log.txt
export DISPLAY=:0
kdialog --msgbox "$(upower -i /org/freedesktop/UPower/devices/battery_BAT0| grep -E "state|to\ full|percentage")"
crontab(作为 sudo):
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/home/king/Scripts
#
# m h dom mon dow command
* * * * * bash /home/king/Scripts/my_battery_script
我已检查以确保:
the script is executable
root user owns the script
I can run the script from within a shell using ./my_battery_script
I can run other bash scripts from within cron (I created a test script that wrote to a text file). Worked fine
kdelibs-full is installed
为什么这个脚本不运行?
编辑:更多细节
脚本实际执行的日志如下:
++ date
+ printf %s Mon Jan 11 22:29:01 EST 2016 _END
MonJan1122:29:01EST2016_END+ export DISPLAY=:0
+ DISPLAY=:0
++ upower -i /org/freedesktop/UPower/devices/battery_BAT0
++ grep -E 'state|to\ full|percentage'
++ cat /sys/class/thermal/thermal_zone0/temp
++ awk '{print "deg C: "$1/1000}'
+ /usr/bin/kdialog --msgbox ' state: discharging
percentage: 58% \n cpu temp: deg C: 44.5'
No protocol specified
kdialog: cannot connect to X server :0
【问题讨论】:
-
既然可以使用
#!/bin/bash,为什么还要使用#!/bin/sh?我认为这不会解决您的问题,但是您使用的是什么操作系统?较旧的 Unixn 可能不支持 crontab 中的PATH=...,但如果您使用的是 Linux,那应该不是问题。为什么不添加kdialog的完整路径。这不是使用窗口程序的交互式程序吗?对于不是从用户会话启动的程序,您期望会发生什么?您认为root将接管谁的会话来显示该输出?我没有你的环境,所以我无法进一步提供帮助。祝你好运! (编辑您的 Q 以获取更多详细信息)。 -
DISPLAY 对于现代 X 系统来说是不够的——您还需要身份验证 (Xauthority)。
-
将脚本的 stderr 重定向到日志文件,并将其内容包含在您的问题中。即:
exec 2>/path/to/file.log作为(比如说)第二行左右。您也可以exec 2>>battery_log.txt,然后您回显或打印>&2的任何内容都将转到那里,而无需为该单个命令重新打开文件。 -
(...正如 shellter 所说,让你的 shebang 和手动 shell 调用不一致是不好的做法;对两者使用相同的 shell --
bash和/bin/sh是 不是相同的 shell -- 否则你的脚本可能会根据它的启动方式而表现不同)。 -
该行放在哪个文件中? crontab,或者我可以从脚本本身重定向输出吗?