根本原因是crontab运行环境不加载shell profile,PATH极短导致找不到php或yii;解决办法是使用绝对路径调用(如/usr/bin/php)、确保yii文件可执行且无#!/usr/bin/env php陷阱、显式声明PATH、检查console配置及数据库连接、添加flock锁防重复、强制日志重定向。

crontab里执行php yii报“Command not found”或“PHP not found”
根本原因是crontab运行环境不加载你的shell profile,PATH极短,找不到php或yii。别指望它认识你终端里敲的命令。
解决办法不是改PATH变量(虽然也能行),而是直接用绝对路径:
-
/usr/bin/php路径必须准确——运行which php确认,别抄网上默认值 -
/var/www/myapp/yii必须是绝对路径,且该文件存在、可读、有执行权限(chmod +x) - crontab行首显式声明PATH更稳妥:
PATH=/usr/local/bin:/usr/bin:/bin
手动能跑,crontab里连DB都连不上
Console命令用的是config/console.php,不是web/config/main.php。很多人只配了Web端的db组件,忘了在console配置里补上。
检查点很具体:
- 打开
config/console.php,确认里面有'components' => ['db' => [...]] - 如果用了
common/config/main-local.php等分环境配置,确保console也加载了对应文件 - 连接MySQL时若报
Access denied,注意crontab环境下可能没加载~/.my.cnf,得显式传host/user/pass
yii脚本第一行#!/usr/bin/env php导致crontab调用失败
这行看似无害,实则是crontab里最常翻车的点——env在crontab里找不到php,直接退出,连错误都不报。
两种修法,任选其一:
- 直接改
yii文件第一行:把#!/usr/bin/env php换成#!/usr/bin/php(或你真实的php路径) - 或者用软链统一入口:
ln -sf /usr/local/php/bin/php /usr/local/bin/php,再保持#!/usr/bin/env php
改完记得chmod +x yii,否则Linux不认它为可执行文件。
任务跑了一半就卡住或重复执行
Console命令没设超时、没加锁,crontab按分钟触发,上次还没结束,下次又来了——结果数据错乱、日志刷屏。
关键动作只有两个:
- 所有耗时操作必须包在
try...catch里,捕获异常后return 1,让crontab知道失败了 - 加锁不是可选项:用
omnilight/yii2-scheduling自带的文件锁,或自己用flock包装命令:flock -n /tmp/clean.lock -c "php yii clean-cache/run"
日志重定向别省:>> /var/log/yii-cron.log 2>&1,否则stdout/stderr全丢进黑洞,出问题时你连“它到底跑没跑”都不知道。


















