【问题标题】:Crontab not executing Python script on UbuntuCrontab 未在 Ubuntu 上执行 Python 脚本
【发布时间】:2025-12-08 18:45:02
【问题描述】:

我有一个包含以下代码的 Python 脚本:

import subprocess
import sys

default = "Take a 20 second break - look at least 20 feet away!"
message = sys.argv[1] if len(sys.argv) > 1 else default

def sendmessage(message):
    subprocess.Popen(['notify-send', message])
    return

sendmessage(message)

调用takebreak.py,它将发送系统通知。

当我尝试像这样使用 crontab 自动化它时:

* * * * * /usr/bin/python /home/polo/git-repositories/takebreak/takebreak.py

它不起作用。运行命令

/usr/bin/python /home/polo/git-repositories/takebreak/takebreak.py

在终端中确实有效,这意味着它不是文件位置问题,而是与cron 有关。有什么想法吗?

EDIT1:

在调试并查看日志之后,我可以验证 cron 实际上每分钟都在执行命令 export DISPLAY=:0; /usr/bin/python /home/polo/git-repositories/takebreak/takebreak.py,就像我设置的那样,但由于某种原因,这个命令虽然应该发送系统通知,但不是这样做。 有什么想法吗?

EDIT2:

解决方案是添加一些地址总线的东西(忘记确切的代码),我在另一篇文章中找到了,最终修复了它。不幸的是,这里的答案或 cmets 都没有帮助解决问题,但无论如何感谢!

【问题讨论】:

  • 我的 crontab 确实在运行,但由于某种原因,有问题的命令不起作用。只输入* * * * * export DISPLAY=:0; /usr/bin/notify-send blah 不会显示任何内容
  • 我很难理解上面代码中的解决方案。我应该在我的主代码中添加一个 DBUS_SESSION_BUS_ADDRESS 吗?地址是什么?
  • 首先,我的建议是运行env|grep DBUS 并将其硬编码在crontab 中,就像Will 的回答中的$PATH 一样。这会告诉你它是否能解决问题。如果是这样,在我链接到的那个答案中,有一些关于如何做的建议。如果它是一个 bash 脚本会更容易,你必须找出最好的方法,无论是从 Python 还是通过将环境变量转储到某个地方并从 crontab 中使用它。

标签: python ubuntu cron crontab


【解决方案1】:

最有可能的是,当从crontab 运行时,notify-send 不在您的$PATH 中。首先,弄清楚它的存储位置:

$ which notify-send
/usr/bin/notify-send

对我来说,它在/usr/bin

crontab 文件 (crontab -e) 的顶部,设置 $PATH

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

如果您想包含之前可能已经设置的任何 $PATH(更安全),请改为:

PATH="${PATH}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

如果/usr/bin 中未安装命令,请确保其中包括安装命令的目录。

当然,另一种选择是在 Python 脚本中简单地指定完整的命令路径:

subprocess.Popen(['/usr/bin/notify-send', message])

【讨论】:

  • 在脚本中指定绝对命令路径不是更好吗?设置 crontab PATH 可能会产生副作用。
  • 我会说不——那么脚本的可移植性较差,因为它依赖于安装在指定位置的 libnotify 工具。我添加到我的答案中,并提出了一种更安全的方式来修改$PATH,以及更改 Python 脚本以使用命令的绝对路径。
  • 两种方法都不起作用,cat /var/log/syslog | grep crontab 返回(在编辑等中)以下行:Mar 30 19:31:01 polo cron[634]: (polo) RELOAD (crontabs/polo)
  • 让我们尝试将标准错误输出写入文件并查看它。将 >/tmp/cron-error.log 2>&1 添加到 crontab 行的末尾,然后查看 /tmp/cron-error.log 并查看它的内容。
  • 我之前试过这个,但等待几分钟后没有出现日志(crontab现在设置为每分钟运行一次)