crontab未执行的首要原因是cron服务未运行,需用systemctl status检查并启动;其次注意语法、路径、环境变量及日志重定向等细节。

crontab 为什么没执行?先看 cron 服务有没有在跑
定时任务不触发,八成不是语法写错了,而是 crond 根本没起来。Linux 不像 Windows 计划任务会自动兜底,crond 进程挂了,所有 crontab 都是废纸。
- Debian/Ubuntu 系统检查:
systemctl status cron;CentOS/RHEL 系统用:systemctl status crond - 如果显示
inactive (dead),立刻启动:sudo systemctl start cron(或crond) - 顺手设开机自启:
sudo systemctl enable cron,否则重启后又失效
注意:有些最小化安装的系统(比如某些 Docker 镜像或云服务器精简版)压根没装 vixie-cron,运行 crontab -e 报“command not found”时,得先 yum install vixie-cron crontabs 或 apt install cron。
用户级任务用 crontab -e,别直接改 /var/spool/cron/
每个用户的定时任务都存在 /var/spool/cron/<username></username>,但你**不该手动编辑这个文件**——它不校验语法,保存即覆盖,一逗号打错就清空整个 crontab。
- 正确做法永远是:
crontab -e(当前用户)或sudo -u www-data crontab -e(切换用户) - 保存退出后,系统会自动语法检查并重载,失败时会明确提示哪一行出错
- 想看当前所有任务:
crontab -l;想清空全部:crontab -r(慎用!无确认)
示例:每天凌晨 2 点备份,写成:0 2 * * * /bin/bash /home/user/backup.sh。注意命令必须用绝对路径,bash 也得写全,因为 cron 的默认 PATH 极其有限(通常只有 /usr/bin:/bin)。
脚本在终端能跑,cron 里却静默失败?环境不一致是主因
最典型的现象:手动执行 /home/user/script.sh 没问题,加进 crontab 后日志空、文件没生成、邮件也没收到——大概率是环境变量、工作目录或 PATH 导致的。
-
cd /your/work/dir && /path/to/script.sh:显式指定工作目录,避免相对路径失效 - 在 crontab 文件顶部加一行:
PATH=/usr/local/bin:/usr/bin:/bin,补全常用命令路径 - 加上输出重定向:
0 2 * * * /bin/bash /home/user/backup.sh &>> /var/log/backup.log,把 stdout/stderr 全捕获,排查才有依据 - 如脚本依赖
LANG或自定义变量,也在 crontab 文件开头声明:LANG=en_US.UTF-8
别信“脚本第一行写了 #!/bin/bash 就万事大吉”,cron 启动时根本不读 shebang,它只认你写在命令里的解释器路径。
系统级任务该放哪儿?优先选 /etc/cron.d/ 而非 /etc/crontab
需要以特定用户(比如 www-data 或 postgres)身份运行、且要长期维护的任务,别硬塞进 /etc/crontab——那个文件是系统保留区,多人协作时容易误改。
- 新建独立任务文件:
sudo nano /etc/cron.d/myapp-healthcheck - 内容格式多一列用户名:
*/5 * * * * www-data /usr/bin/curl -sf http://localhost/health > /dev/null - 必须设权限:
sudo chmod 644 /etc/cron.d/myapp-healthcheck,否则 cron 直接忽略 - 文件名不能带点或扩展名(
myapp-healthcheck.bak不会被加载)
改完不用重启服务,但建议 reload 一下确保识别:sudo systemctl reload cron(或 crond)。/etc/cron.hourly 等目录适合“开箱即用”的简单轮询,不适合带参数或需精细控制的任务。
真正麻烦的从来不是怎么写那行 * * * * *,而是 cron 启动时没读你的环境变量、脚本里用了 ~ 当前用户家目录、或者日志被丢进黑洞连报错都看不到——这些细节不盯住,定时任务就永远活在“好像该跑但没跑”的灰色地带。










