crontab执行php脚本失败的根本原因是环境差异:cron默认path窄、不加载bash配置、不维持进程、路径权限易错;须用绝对路径、显式设置path与runtime_path、重定向日志并验证权限。

crontab 执行 PHP 脚本时 command not found
根本原因是 cron 默认只认 /usr/bin:/bin,而 ThinkPHP 6 的 php 命令很可能在 /usr/local/bin/php,composer 或 artisan 类命令更可能位于 ~/.local/bin/。手动执行时你用的是完整 PATH,cron 不加载 ~/.bashrc,自然找不到。
实操建议:
- 用
which php查出真实路径,比如返回/usr/local/bin/php,那就必须写死这个路径,不能只写php - 在 crontab 文件顶部加一行:
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/home/youruser/.local/bin - 如果脚本里还调用了
mysql、curl等,同样得确认它们的which结果,避免“半途失败”
TP6 的 command 命令在 cron 下静默退出
ThinkPHP 6 的定时任务本质是通过 php think timer:run 启动一个常驻进程,但 cron 每次都是新 shell,无法维持长连接——所以你写的 * * * * * cd /var/www/app && php think timer:run 实际上每次只跑了一秒就退出,根本没生效。
正确做法不是让 cron 反复拉起 timer:run,而是:
- 用
php think schedule:run(单次执行)替代timer:run(守护进程) - 确保命令前加绝对路径:
/usr/local/bin/php /var/www/app/think schedule:run - 加上输出重定向,方便排查:
/usr/local/bin/php /var/www/app/think schedule:run >> /var/www/app/storage/logs/schedule.log 2>&1
脚本内文件操作失败:open(/runtime/cache/xxx) failed
TP6 默认把缓存、日志写到 runtime/ 目录,但 cron 执行时当前目录不一定是项目根目录,且用户权限可能不对。常见报错是 failed to open stream: Permission denied 或路径解析成 /root/runtime/。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
关键动作:
- 所有路径必须用绝对路径:在 TP6 的
config/app.php中显式设'runtime_path' => '/var/www/app/runtime/', - 在 crontab 条目里先
cd到项目根目录:* * * * * cd /var/www/app && /usr/local/bin/php think schedule:run - 确认
runtime/目录属主是 cron 运行用户(比如 www-data),且有写权限:chown -R www-data:www-data /var/www/app/runtime
日志空、无报错、任务像没跑过
这是最让人抓狂的情况:crontab -l 看得到任务,systemctl status cron 显示正常,但就是没日志、没效果。大概率是输出被吞了,或错误没被捕获。
必须做的三件事:
- 给每条 crontab 加
2>&1重定向 stderr,否则 PHP 错误(比如扩展没装)直接丢弃 - 别依赖
mail接收输出——多数服务器没配 mail 服务,> /tmp/cron-debug.log 2>&1更可靠 - 在 TP6 的
schedule:run命令前加env -i模拟纯净环境:env -i PATH=/usr/local/bin:/usr/bin:/bin /usr/local/bin/php /var/www/app/think schedule:run,能快速暴露环境依赖问题
TP6 定时任务本身没问题,问题永远在 cron 和 PHP 运行环境之间那层薄薄的隔阂——漏掉任意一个路径、权限或环境变量,它就静默消失。










