我知道有很多类似的问题,并且我尝试了很多方法,但仍然无法解决。
我有计划在 10 分钟内运行的 cronjob。我可以看到/var/log/syslog
它正常运行
Oct 21 07:30:01 stan CRON[7604]: (stan) CMD (stan /home/stan/update.sh)
Oct 21 07:40:01 stan CRON[8304]: (stan) CMD (stan /home/stan/update.sh)
Oct 21 07:50:01 stan CRON[8751]: (stan) CMD (stan /home/stan/update.sh)
Oct 21 08:00:01 stan CRON[9347]: (stan) CMD (stan /home/stan/update.sh)
Oct 21 08:10:01 stan CRON[9789]: (stan) CMD (stan /home/stan/update.sh)
update.sh
调用php
更新数据库的脚本。当我直接从终端运行时,shell 脚本数据库已更新,并且运行正常
./update.sh
但 cronjob 不会更新数据库。我的 cron
*/10 * * * * stan /home/stan/update.sh
shell 脚本生成的命令是
/usr/bin/php /var/www/html/site/update.php
两个文件的权限
-rwxrwxr-x 1 stan stan 123 Oct 20 15:09 update.sh
-rwxr-xr-x 1 stan www-data 1301 Oct 21 07:52 /var/www/html/site/update.php
知道可能是什么问题吗?
更新:路径
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
update.sh
$ cat update.sh
#!/bin/sh
list="/var/www/html/site"
config="/usr/bin/php"
for i in "$list"
do
"$config" "$i"/update.php
done
参考我昨天的问题是关于 shell 和 php,现在的问题是关于 cron。
$ whereis php
php: /usr/bin/php5.6 /usr/bin/php /usr/lib/php /etc/php /usr/include/php /usr/share/php5.6-intl /usr/share/php7.0-mbstring /usr/share/php7.0-common /usr/share/php5.6-curl /usr/share/php5.6-gd /usr/share/php5.6-mcrypt /usr/share/php5.6-common /usr/share/php5.6-readline /usr/share/php5.6-json /usr/share/php /usr/share/php5.5-mbstring /usr/share/php5.6-opcache /usr/share/php5.6-mbstring /usr/share/php5.6-xml /usr/share/php5.5-common /usr/share/php5.6-mysql /usr/share/man/man1/php.1.gz
$ which php
/usr/bin/php
答案1
您似乎混淆了两种不同的调用cron
作业的方法。
Ubuntu 继承了 Debian 一个有点令人困惑的政策,它既支持crontabs
存储在假脱机区域中的用户/var/spool/cron
,也支持从中运行的系统范围的 cron 作业/etc/crontab
和文件中运行的策略/etc/cron.d
。
/etc/crontab
在文件中或通过文件指定的作业/etc/cron.d
需要一个额外的字段,以允许它们以不同的用户身份运行,因此格式类似于
*/10 * * * * <username> <command> <args>
通过假脱机区域设置的作业crontab -e
(或sudo crontab -e
为 root 设置)已经属于特定用户,并且不需要用户字段
*/10 * * * * <command> <args>
如果您在通过命令设置的 cron 作业中包含用户名字段crontab -e
,它将被误解为命令:正如我们从您的日志输出中看到的那样,
Oct 21 07:30:01 stan CRON[7604]: (stan) CMD (stan /home/stan/update.sh)
cron
解释stan
为命令和争论 /home/stan/update.sh
解决方案很简单,就是stan
从您的 crontab 中删除用户名。
答案2
一些可能出现的问题:
1)你可能没有#!/bin/sh
在update.sh
2) PHP 可能需要执行额外的命令,但 cron 任务的执行无需设置 PATH 变量。要修复此问题,请echo $PATH
在命令运行的终端上使用,然后使用export PATH=...
,将 替换为上面...
的输出echo $PATH
update.sh
3) PHP 可能需要其他环境变量才能运行。在调用之前,请找到它们并将其导出/usr/bin/php
。
编辑
好吧,不是 1)
打开一个新窗口(或者一个新的ssh连接)并执行:
for i in `env | sed 's/=.*//'` ; do unset $i ; done
这将取消设置所有环境变量,包括 PATH。然后尝试:
/usr/bin/php /var/www/html/site/update.php
然后在此处发布错误消息。
答案3
问题是 crontab 的路径变量搜索非常有限。必须添加完整路径才能添加到所有脚本和子脚本中的几乎所有命令中。或者,您可以将与手动运行脚本时相同的搜索路径添加到脚本中。
更改自:
#!/bin/sh
list="/var/www/html/site"
config="/usr/bin/php"
for i in "$list"
do
"$config" "$i"/update.php
done
改成:
#!/bin/sh
PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
list="/var/www/html/site"
config="/usr/bin/php"
for i in "$list"
do
"$config" "$i"/update.php
done
笔记:
添加的路径搜索取自您在问题中发布的内容,在手动运行脚本时有效。如果您知道哪个路径包含脚本中的命令以及脚本调用的任何脚本或命令update.php
,那么这些就是唯一需要添加的搜索路径。