【问题标题】:bash script with kdialog not running from cron带有 kdialog 的 bash 脚本未从 cron 运行
【发布时间】: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

为什么这个脚本不运行?

编辑:更多细节

  • 在 Linux Mint 17.3 上运行

  • 内核:3.19.0-32-通用

  • 我期望发生的事情:当计时器在 cron 中触发时,它会启动脚本(以 root 身份)。该脚本基于 DISPLAY 变量(或者我在其他论坛上阅读)使用自己的显示(不确定术语)来显示电池消息

    脚本实际执行的日志如下:

    ++ 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,或者我可以从脚本本身重定向输出吗?

    标签: bash cron


    【解决方案1】:
    + /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
    

    假设您实际上有一个 X 服务器为显示器 0 运行,这通常意味着您有一个操作系统级别的安全措施来阻止 root 访问该显示器。

    这里的简单答案是在您的用户帐户下运行此 cron 作业,而不是以 root 身份运行。

    【讨论】:

      【解决方案2】:

      尝试在脚本中添加 kdialog 的路径,好像找不到命令

      【讨论】:

      • 如何找到 kdialog 安装位置的路径?
      • @Rilcon42,type kdialog。 (还有较旧的外部命令 which,但 type 更准确地显示了您的 shell 实际执行的操作,即使涉及别名/函数/等)。
      • 定位 kdialog 或 find . -name "kdialog"
      • @LevBystritskiy,如果 OP 可以在他们的 X 会话中(在 cron 之外)成功运行命令,则几乎没有必要——在这种情况下,我们已经知道它在他们的用户帐户的 PATH 中,因此他们可以交互地使用 @ 987654324@ 或 which 在该会话中。
      猜你喜欢
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2012-10-22
      • 2017-05-28
      • 2018-07-05
      • 2013-02-26
      • 2011-08-10
      • 1970-01-01
      相关资源
      最近更新 更多