提问人:bor 提问时间:3/30/2014 最后编辑:Gopal Chitaliabor 更新时间:6/14/2023 访问量:249150
CronJob 未运行
CronJob not running
问:
我已经在ubuntu环境中为root用户设置了一个cronjob,如下所示crontab -e
34 11 * * * sh /srv/www/live/CronJobs/daily.sh
0 08 * * 2 sh /srv/www/live/CronJobs/weekly.sh
0 08 1 * * sh /srv/www/live/CronJobs/monthly.sh
但是 cronjob 不运行。我尝试检查 cronjob 是否正在运行,并给出进程 ID 3033。shell 脚本调用 python 文件并用于发送电子邮件。运行 python 文件是可以的。它没有错误,但 cron 没有运行。daily.sh 文件中包含以下代码。pgrep cron
python /srv/www/live/CronJobs/daily.py
python /srv/www/live/CronJobs/notification_email.py
python /srv/www/live/CronJobs/log_kpi.py
答:
跆拳道?!我的 cronjob 不运行?!
下面是调试未运行 cronjobs 的清单指南:
- Cron 守护程序是否正在运行?
- 运行并查找 cron。
ps ax | grep cron
- Debian:或
service cron start
service cron restart
- cron 有效吗?
* * * * * /bin/echo "cron works" >> /tmp/file
- 语法正确吗?见下文。
- 显然,您需要对要将输出重定向到的文件具有写入权限。当前不存在的唯一文件名应始终是可写的。
/tmp
- 可能还会添加包括标准误差和标准输出,或者将标准误差单独输出到另一个文件
2>&1
2>>/tmp/errors
- 该命令是否独立工作?
- 通过在 CLI 上执行试运行来检查脚本是否存在错误
- 测试命令时,请以您正在编辑其 crontab 的用户身份进行测试,该用户可能不是您的登录名或 root 用户
- cron 可以运行您的作业吗?
- 检查或是否有错误。
/var/log/cron.log
/var/log/messages
- Ubuntu的:
grep CRON /var/log/syslog
- 红帽:
/var/log/cron
- 检查权限
- 在命令上设置可执行文件标志:
chmod +x /var/www/app/cron/do-stuff.php
- 如果将命令的输出重定向到文件,请验证您是否有权写入该文件/目录
- 检查路径
- 检查 she-bangs / hashbangs 线
- 不要依赖像 这样的环境变量,因为它们的值在 cron 下可能与在交互式会话下不同。请参阅如何让 CRON 调用正确的 PATH
PATH
- 调试时不要抑制输出
- 常用的就是这种抑制:
30 1 * * * command > /dev/null 2>&1
- 通过完全删除重新启用标准输出或标准错误消息输出;或者重定向到您具有写入访问权限的位置中的文件:将 Standard Output 和 Standard Error 追加到调用用户的主目录中。
>/dev/null 2>&1
>>cron.out 2>&1
cron.out
- 如果不重定向作业的输出,守护程序将尝试通过电子邮件向您发送任何输出或错误消息。检查您的收件箱(也许只是如果您没有邮件客户端)。如果邮件不可用,请检查主目录中命名的文件,或者检查系统日志条目,指出输出已被丢弃。尤其是在后一种情况下,可能会编辑作业以将重定向添加到文件,然后等待作业运行,并检查日志文件中是否有错误消息或其他有用的反馈。
cron
more $MAIL
dead.letter
- 如果您试图找出失败的原因,则此文件中将显示错误消息。阅读并理解它。
还是不行?哎呀!
- 提高 cron 调试级别
- Debian的
- 在
/etc/default/cron
- 设置
EXTRA_OPTS="-L 2"
service cron restart
tail -f /var/log/syslog
以查看已执行的脚本
- 在
- Ubuntu的
- 在
/etc/rsyslog.d/50-default.conf
- 添加或注释掉行
cron.* /var/log/cron.log
- 重新加载记录器
sudo /etc/init.d/rsyslog restart
- 重新运行 cron
- 打开并查找详细的错误输出
/var/log/cron.log
- 在
- 提醒:完成调试后,停用日志级别
- 运行 cron 并再次检查日志文件
Cronjob 语法
# Minute Hour Day of Month Month Day of Week User Command
# (0-59) (0-23) (1-31) (1-12 or Jan-Dec) (0-6 or Sun-Sat)
0 2 * * * root /usr/bin/find
此语法仅对用户适用。常规用户语法没有 User 字段(不允许常规用户以任何其他用户身份运行代码);root
crontab
# Minute Hour Day of Month Month Day of Week Command
# (0-59) (0-23) (1-31) (1-12 or Jan-Dec) (0-6 or Sun-Sat)
0 2 * * * /usr/bin/find
Crontab 命令
crontab -l
- 列出用户的所有 cron 任务。
crontab -e
,对于特定用户:crontab -e -u agentsmith
- 启动 crontab 文件的编辑会话。
- 当您退出编辑器时,将自动安装修改后的 crontab。
crontab -r
- 从 cron 后台处理程序中删除 crontab 条目,但不从 crontab 文件中删除 crontab 条目。
评论
PATH
crontab
*/5
3,11,19
cron
最后,我找到了解决方案。以下是解决方案:-
切勿在通过 crontab 执行的 python 脚本中使用相对路径。 我做了这样的事情:-
import os import sys import time, datetime CLASS_PATH = '/srv/www/live/mainapp/classes' SETTINGS_PATH = '/srv/www/live/foodtrade' sys.path.insert(0, CLASS_PATH) sys.path.insert(1,SETTINGS_PATH) import other_py_files
永远不要压制 crontab 代码,而是使用 mailserver 并检查用户的邮件。这样可以更清楚地了解正在发生的事情。
评论
cron
cron
* * * * * whatever >>filename 2>&1
filename
有时,cron 需要运行的命令位于 cron 无权访问的目录中,通常在用户主目录的权限为 700 且命令位于该目录中的系统上。
评论
cron
我发现了用户的crontab未运行的另一个原因:主机文件上不存在主机名:
user@ubuntu:~$ cat /etc/hostname
ubuntu
现在 hosts 文件:
user@ubuntu:~$ cat /etc/hosts
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
这是在 Ubuntu 14.04.3 LTS 上,修复它的方法是将主机名添加到主机文件中,因此它类似于这样:
user@ubuntu:~$ cat /etc/hosts
127.0.0.1 ubuntu localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
我想补充我学到的 2 点:
- 放在 /etc/cron.d/ 中的 Cron 配置文件不应包含点 (.)。否则,它不会被 cron 读取。
- 如果运行命令的用户不在 /etc/shadow 中。不允许调度 cron。
裁判:
- http://manpages.ubuntu.com/manpages/xenial/en/man8/cron.8.html
- https://help.ubuntu.com/community/CronHowto
评论
.d
run-parts
crontab 失败的另一个原因:对角色的特殊处理。%
从手册文件:
The entire command portion of the line, up to a newline or a
"%" character, will be executed by /bin/sh or by the shell specified
in the SHELL variable of the cronfile. A "%" character in the
command, unless escaped with a backslash (\), will be changed into
newline characters, and all data after the first % will be sent to
the command as standard input.
在我的特殊情况下,我用来为我的脚本生成参数,但它悄无声息地失败了。当我检查并看到我的命令在符号处被截断时,我终于发现了发生了什么。你需要像这样转义它:date --date="7 days ago" "+%Y-%m-%d"
syslog
%
date --date="7 days ago" "+\%Y-\%m-\%d"
有关详细信息,请参阅此处:
http://www.ducea.com/2008/11/12/using-the-character-in-crontab-entries/
评论
sh /path/script.sh /path/$(date +%Y-%m-%d).txt
sh /path/script.sh /path/$(date +\%Y-\%m-\%d).txt
对我来说,解决方案是 cron 尝试运行的文件位于加密目录中,更具体地说是 /home/ 上的用户目录。尽管 crontab 配置为 root,但由于正在运行的脚本存在于 /home/ 的加密用户目录中,因此 cron 只能在用户实际登录时读取此目录。要查看该目录是否已加密,请检查此目录是否存在:
/home/.ecryptfs/<yourusername>
如果是这样,那么你有一个加密的主目录。
我的解决方法是将脚本移动到非=加密目录中,并且每个目录都工作正常。
我遇到了同样的问题,crons 没有运行。 我们通过更改权限和所有者来修复 正如我们在 crontab 中提到的,crons 成为 root 所有者,并且 Cronjobs 644 授予权限
评论
我通过运行以下命令在 Ubuntu 16.04 服务器上找到了有用的调试信息:
systemctl status cron.service
就我而言,我被善意地告知我在评论行中留下了评论“#”:
Aug 18 19:12:01 is-feb19 cron[14307]: Error: bad minute; while reading /etc/crontab
Aug 18 19:12:01 is-feb19 cron[14307]: (*system*) ERROR (Syntax error, this crontab file will be ignored)
这也可能是时区问题。
Cron 使用当地时间。
运行该命令以查看计算机时间,并确保 crontab 处于同一时区。timedatectl
要添加另一个点,/etc/cron.d 中的文件必须在末尾包含一个空换行符。这可能与卢西亚诺的回应有关,该回应指出:
The entire command portion of the line, up to a newline or a "%"
character, will be executed
评论
已经有很多答案了,但没有一个对我有帮助,所以我会在这里添加我的答案,以防它对其他人有用。
在我的情况下,我的 cronjobs 一直在工作,直到电力短缺切断了我的 Raspberry Pi 的电源。克伦被破坏了。我认为它恰好在短缺发生时运行了一个很长的 python 脚本。上面的主要答案中没有任何内容对我有用。然而,解决方案非常简单。我只需要强制重新安装 cron :
sudo apt-get --reinstall install cron
在此之后,它立即起作用。
我对下面的链接有类似的问题。
我的问题
我的问题是 cron / crontab 不会执行我的 bash 脚本。该 bash 脚本执行了一个 Python 脚本。
原始 BASH 文件
#!/bin/bash
python /home/frosty/code/test_scripts/test.py
Python 文件 (test.py)
from datetime import datetime
def main():
dt_now = datetime.now()
string_now = dt_now.strftime('%Y-%m-%d %H:%M:%S.%f')
with open('./text_file.txt', 'a') as f:
f.write(f'wrote at {string_now}\n')
return None
if __name__ == '__main__':
main()
我收到的错误
File "/home/frosty/code/test_scripts/test.py", line 7
string_to_write = f'wrote at {string_now}\n'
^
SyntaxError: invalid syntax
这个错误没有意义,因为代码从 bash 文件和 python 文件执行时没有错误。
** 注意 -> 确保在文件中不禁止显示输出。我通过在命令后添加将输出发送到文件。下面是我的 crontab -e 条目crontab -e
>>/path/to/cron/output/file.log 2>&1
*/5 * * * * /home/frosty/code/test_scripts/echo_message_sh >>/home/frosty/code/test_scripts/cron_out.log 2>&1
问题
cron 使用了错误的 python 解释器,可能是语法错误的 Python 2。
我是如何解决问题的
我将我的 bash 文件更改为以下内容
#!/bin/bash
conda_shell=/home/frosty/anaconda3/etc/profile.d/conda.sh
conda_env=base
source ${conda_shell}
conda activate ${conda_env}
python /home/frosty/code/test_scripts/test.py
我将我的 python 文件更改为以下内容
from datetime import datetime
def main():
dt_now = datetime.now()
string_now = dt_now.strftime('%Y-%m-%d %H:%M:%S.%f')
string_file = '/home/frosty/code/test_scripts/text_file.txt'
string_to_write = 'wrote at {}\n'.format(string_now)
with open(string_file, 'a') as f:
f.write(string_to_write)
return None
if __name__ == '__main__':
main()
评论
python
/opt/local/python3.10/bin/python
python
venv
venv
$HOME/myprovect/venv
$HOME/myproject/script.py
activate
$HOME/myproject/venv/bin/python $HOME/myproject/script.py
由于这正在成为解决问题的规范,请允许我添加一个具体但相当复杂的问题:如果您尝试从 运行 GUI 程序,您可能做错了。cron
cron
常见症状是收到有关未设置或作业进程无法访问显示的错误消息。DISPLAY
cron
简而言之,这意味着您尝试运行的程序正在尝试在 X11(或 Wayland 等)显示器上呈现某些内容,并且失败了,因为它没有连接到图形环境,或者实际上根本没有任何类型的输入/输出工具,除了能够读取和写入文件,如果系统配置为允许这样做,则发送电子邮件。cron
出于“我无法运行我的图形作业”的目的,让我们粗略地指出此问题的三种常见情况。
可能确定您尝试实现的案例,并搜索有关该特定方案的相关问题以了解更多信息,并使用实际代码找到实际解决方案。cron
如果你正在尝试开发一个与用户通信的交互式程序,你需要重新考虑你的方法。一个常见但重要的安排是将程序一分为二:一个后端服务,它可以从 运行,但没有任何用户可见的交互设施,以及一个前端客户端,当用户想要与后端服务通信时,用户从他们的 GUI 运行。
cron
如果用户客户端需要或希望在登录时自动运行,则只需将其添加到用户的 GUI 启动脚本中即可。
我想后端服务可以从 启动,但如果它需要 GUI 有用,也许可以从 X11 服务器的启动脚本启动它;如果没有,可能从常规启动脚本(现在,或更传统的类似系统启动目录)运行它。1
cron
systemd
/etc/rc.local
如果您尝试在不与真实用户 2 交互的情况下运行 GUI 程序,您可以设置一个“无头”X11 服务器 3 并运行一个作业,该作业启动该服务器,运行您的作业,然后退出。
cron
也许你的工作应该简单地运行一个合适的 X11 服务器(独立于任何交互式 X11 服务器,该服务器管理系统可用的实际物理显示器和附加的显卡和键盘),并向其传递一个配置,该配置在启动并运行后运行您想要运行的客户端。(有关一些实际注意事项,另请参阅下一点。
cron
您运行计算机的唯一目的是在 GUI 中显示特定应用程序,并且您希望在计算机启动时启动该应用程序。
也许您的启动脚本应该简单地运行 GUI(X11 或其他)并挂接到其启动脚本中,以便在 GUI 启动并运行后也运行客户端程序。换句话说,你不需要这里;只需配置启动脚本以运行桌面 GUI,并将桌面 GUI 配置为将应用程序作为(可能是自动的,来宾?)登录序列的一部分运行。4
cron
有一些方法可以在系统的主显示器 () 上运行 X11 程序,但从作业中执行此操作通常会有问题,因为该显示器通常保留给登录并启动图形桌面的第一个用户的实际交互使用。在单用户系统上,如果该用户也是您,您也许可以忍受副作用,但这往往会带来不便的后果,并且扩展性很差。DISPLAY=:0.0
cron
另一个复杂因素是决定以哪个用户身份运行作业。像后端服务这样的共享系统资源可以而且可能应该由它运行(尽管理想情况下,它有一个专用的系统帐户,一旦它获得了对它需要的任何特权资源的访问权限,它就会切换到该帐户),但任何涉及 GUI 的东西都绝对不应该像在任何时候一样运行。cron
root
root
一个相关但独特的问题是以任何有意义的方式与用户进行交互。如果你能识别用户的活动会话(在某种程度上,这甚至一开始就被明确定义了),你如何在不干扰他们中间的任何其他事情的情况下吸引他们的注意力?但更根本的是,你如何找到它们?如果他们根本没有登录,那你会怎么做?如果是,您如何确定它们是否处于活动状态和可用状态?如果他们多次登录,他们使用的是哪个终端,中断该会话是否安全?同样,如果它们登录到 GUI,如果它们实际上是通过 VNC 或远程 X11 服务器远程登录的,则它们可能会错过您在本地控制台上弹出的窗口。
顺便说一句:在专用服务器(网络托管服务、超级计算集群等)上,如果您安装可以从外部世界连接的交互式图形桌面,甚至根本不会连接到托管公司或机构的服务条款,您甚至可能违反托管公司或机构的服务条款。
1 钩子对于普通用户来说是一种便利,他们在系统出现时没有任何其他工具来运行某些东西,但是如果您无论如何都在那里并且完全控制系统,那么将某些东西隐藏在那里是不方便和晦涩的。使用系统工具启动系统服务。@reboot
cron
root
2 一个常见的用例是运行一个 Web 浏览器,该浏览器需要运行一个完整的 GUI 客户端,但它是以编程方式控制的,并且实际上不需要在任何地方显示任何内容,例如抓取使用 Javascript 的网站,因此需要一个完整的图形浏览器来呈现您想要提取的信息。
另一种是设计不佳的科学或办公软件,它不是为批量使用而编写的,因此即使您只想运行批处理作业,然后立即退出,而无需在任何地方显示任何实际内容,也需要 GUI。
(在后一种情况下,可以查看文档以检查是否有 or or or or or option 或类似选项可以在没有 GUI 的情况下运行该工具,或者可能没有用于非交互式用途的单独实用程序。--batch
--noninteractive
--headless
--script
--eval
3为事实标准解;它运行一个“虚拟帧缓冲区”,计算机可以像向显示器一样吐出像素,但实际上并没有连接到任何显示器硬件。Xvfb
4 这里有几个选项。 最简单的方法是将系统设置为在启动时自动登录特定用户,而无需密码提示,并配置该用户的桌面环境(Gnome 或 KDE 或 XFCE 或其他环境)以从其“启动项”或“登录操作”或“自动启动”或任何可能调用的工具运行您的脚本。如果您需要对环境进行更多控制,可以在没有桌面环境或窗口管理器的情况下运行裸 X11,而只需运行您的脚本即可。或者在某些情况下,也许可以用自定义的东西替换 X11 登录管理器(“欢迎器”)。
X11 堆栈是相当模块化的,在各个层中有几个钩子,您可以在其中运行脚本,作为标准启动过程的一部分,或者完全取代标准层。随着时间的流逝,这些东西在发行版和实现之间往往会有所不同,因此围绕这些问题,这个答案必然是模糊和不完整的。同样,可以尝试找到一个关于如何为您的特定平台(Ubuntu、Raspbian、Gnome、KDE,什么?)和场景做事的现有问题。对于简单的方案,也许可以参看 Ubuntu - 使用可见终端启动时运行 bash 脚本
评论
DISPLAY=:0.0
:0.0
在这里复制我对重复问题的回答。
cron 可能不知道在哪里可以找到 Python 解释器,因为它不共享您用户帐户的环境变量。
有 3 种解决方案:
如果 Python 位于 ,则可以将 cron 作业更改为使用绝对路径:
/usr/bin/python
/usr/bin/python /srv/www/live/CronJobs/daily.py
或者,您也可以使用 向 crontab 添加一个 PATH 值。
PATH=/usr/bin
另一种解决方案是在脚本文件中指定一个解释器,使其可执行,然后在 crontab 中调用脚本本身:
一个。将 shebang 放在 python 文件的顶部: .
#!/usr/bin/python
b.将其设置为可执行文件:
$ chmod +x /srv/www/live/CronJobs/daily.py
c. 将其放入 crontab 中:
/srv/www/live/CronJobs/daily.py
如果 Python 解释器的路径在您的系统上有所不同,请调整该路径。
虽然这个问题的答案已被接受,但我想补充一下对我有用的东西。 引用 URL 是个好主意,如果它包含查询,如果没有引用所有内容,它可能无法工作。
不要忘记将包含“?,=,#,%”的URL放在引号中。
例。https://paystack.com/indexphp?docs/api/#transaction-charge-authorization&date=today 应该在这样的引号中 “https://paystack.com/indexphp?docs/api/#transaction-charge-authorization&date=today”
评论
cron
cron
chmod
cron
未安装 MTA,丢弃输出
我在作为 CRON 作业执行的 PHP 文件时遇到了类似的问题。 当我手动执行文件时,它可以工作,但不能使用 CRON 选项卡。
我收到输出消息:“未安装 MTA,丢弃输出”
Postfix 是 Ubuntu 中的默认邮件传输代理 (MTA),可以使用
sudo apt-get install postfix
但是,当您添加如下日志文件时,也可以输出相同的消息,并且它没有对 /path/to/logfile 的正确写入权限.log
/path/to/php -f /path/to/script.php >> /path/to/logfile.log
如果您使用命令手动创建 cron-log 文件,例如以其他用户身份登录,并在另一个用户(组)的选项卡中添加 CRON,例如 using: ,则可能会出现权限问题。然后 CRON 守护程序尝试写入日志文件并失败,然后尝试使用 Ubuntu 的 MTA 将输出作为电子邮件发送,如果找不到,则输出“未安装 MTA,丢弃输出”。touch
www-data
sudo crontab -u www-data -e
为防止这种情况,请执行以下操作:
- 使用适当的权限创建文件。
- 避免手动创建相关的 CRON 日志文件,在 CRON 选项卡中添加日志,并让日志文件在运行 cron 时自动创建。
评论
CRON 使用不同的时区
一个非常常见的问题是:cron时间设置可能与您的不同。特别是,时区可能不同:
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
您可以运行:
* * * * * echo $(date) >> /tmp/test.txt
这应该会生成一个文件,如下所示:
# cat test.txt
Sun 03 Apr 2022 09:02:01 AM UTC
Sun 03 Apr 2022 09:03:01 AM UTC
Sun 03 Apr 2022 09:04:01 AM UTC
Sun 03 Apr 2022 09:05:01 AM UTC
Sun 03 Apr 2022 09:06:01 AM UTC
如果您使用的是 UTC 以外的 TZ,您可以尝试:
timedatectl set-timezone America/Sao_Paulo
根据您的设置进行替换。America/Sao_Paulo
我不确定是否真的有必要,但您可以运行:
sudo systemctl restart cron.service
在那之后,cron 按我的预期工作:
# cat test.txt
Sun 03 Apr 2022 09:02:01 AM UTC
Sun 03 Apr 2022 09:03:01 AM UTC
Sun 03 Apr 2022 09:04:01 AM UTC
Sun 03 Apr 2022 09:05:01 AM UTC
Sun 03 Apr 2022 09:06:01 AM UTC
Sun 03 Apr 2022 09:07:01 AM UTC
Sun 03 Apr 2022 09:08:01 AM UTC
Sun 03 Apr 2022 09:09:01 AM UTC
Sun 03 Apr 2022 09:10:01 AM UTC
Sun 03 Apr 2022 06:11:01 AM -03
Sun 03 Apr 2022 06:12:01 AM -03
Sun 03 Apr 2022 06:13:01 AM -03
Sun 03 Apr 2022 06:14:01 AM -03
尝试
service cron start
或
systemctl start cron
就我而言,我试图在本地运行 cron。 我检查了状态:
service cron status
它向我展示了:
* cron is not running
然后我简单地启动了服务:
service cron start
如果使用 EC2(Amazon Linux) 实例,请尝试检查文件 /var/spool/mail/[ec2-user] 中的日志:
nano /var/spool/mail/[ec2-user]
评论
PATH