ThinkPHP6定时任务不执行的主因是环境、路径、权限或启动方式问题:crontab环境隔离需写死PHP路径;必须用schedule:run而非timer:run;需显式配置runtime_path并确保目录权限正确;日志缺失时应检查用户、路径及重定向有效性。

ThinkPHP6 定时任务不执行,多数不是代码写错了,而是环境、路径、权限或启动方式没对上。核心问题集中在四个层面:crontab 环境隔离、命令选型错误、运行时路径混乱、权限与日志缺失。
crontab 的 PATH 和 Shell 环境太“干净”
你手动执行 php think schedule:run 没问题,但 crontab 里就报 command not found——因为 cron 不加载 ~/.bashrc,默认 PATH 只有 /usr/bin:/bin,而你的 php 很可能在 /usr/local/bin/php,composer 命令甚至在 ~/.local/bin。
- 用
which php查出真实路径,crontab 中必须写死,比如/usr/local/bin/php - 在 crontab 文件顶部加一行:
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/home/youruser/.local/bin - 如果脚本里调用了
mysql、curl或redis-cli,同样要用which确认路径,避免中途失败
误用 timer:run 而非 schedule:run
TP6 的 timer:run 是常驻进程模式,靠 Swoole 或系统守护维持长连接;但 crontab 每次都是全新 shell,执行完就退出,根本起不到“守着跑”的作用。
- 绝对不要在 crontab 里写:
* * * * * cd /var/www/app && php think timer:run - 应改用单次执行模式:
* * * * * cd /var/www/app && /usr/local/bin/php think schedule:run - 加上日志重定向,方便排查:
>> /var/www/app/storage/logs/schedule.log 2>&1
runtime 目录不在项目根目录,或权限不对
crontab 默认工作目录是 /root(即使你是普通用户,也可能因 systemd 或 sudo 权限提升导致),runtime/cache 就可能被解析成 /root/runtime/cache,自然写入失败。
立即学习“PHP免费学习笔记(深入)”;
- 在
config/app.php中显式设置:'runtime_path' => '/var/www/app/runtime/' - crontab 条目开头先
cd /var/www/app,确保上下文一致 - 确认
runtime/目录属主是 cron 实际运行用户(如www-data或nginx),并赋写权限:chown -R www-data:www-data /var/www/app/runtime && chmod -R 755 /var/www/app/runtime
日志空、没报错、像没跑过
这是最隐蔽的问题:crontab -l 能看到任务,systemctl status cron 显示正常,但 schedule.log 为空,数据库也没记录。
- 先手动执行一遍 crontab 里的完整命令(带 cd + 绝对路径 + 重定向),看是否真能输出
- 检查 crontab 是否属于正确用户:
crontab -u www-data -l,别用 root 写了却让 www-data 运行 - 确认
storage/logs/目录存在且可写,否则schedule.log根本创建不了 - 临时把重定向改成追加到
/tmp/schedule-debug.log,排除路径权限干扰



















