我在/var/www/html/dbsync/index.php
有我的php脚本文件。当cd /var/www/html/dbsync/
和运行php index.php
它完美的工作。
我想通过sh文件调用PHP文件,SH文件的位置如下
/var/www/html/dbsync/dbsync.sh
这是dbsync.sh
文件的内容是:
/usr/bin/php /var/www/html/dbsync/index.php >> /var/www/html/dbsync/myscript.log 2>&1 -q -f
当我cd /var/www/html/dbsync/
和运行./dbsync.sh
它也完美。
现在,如果我按如下方式设置crontab:
1 * * * * /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
但是,此crontab未按预期工作。
有什么不对?
如注释中所示,问题在于您没有定义应该使用哪个程序来执行脚本。考虑到cronjob是在一个微小的环境中执行的;在那里,可以假设不多。这就是我们定义完整路径等的原因。
所以你需要说:
1 * * * * /bin/sh /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
# ^^^^^^^
/bin/sh
是您要用于执行脚本的二进制文件。
否则,您可以设置脚本的执行权限并添加shell-script header告诉它要使用的解释器:
#!/bin/sh
如果这样做,则无需添加二进制文件的路径。
来自Troubleshooting common issues with cron jobs:
使用相对路径。如果你的cron作业正在执行某种脚本,你必须确保在该脚本中只使用绝对路径。例如,如果您的脚本位于/path/to/script.php并且您尝试在同一目录中打开名为file.php的文件,则不能使用相对路径,例如fopen(file.php)。必须从其绝对路径调用该文件,如下所示:fopen(/path/to/file.php)。这是因为cron作业不一定从脚本所在的目录运行,因此必须专门调用所有路径。
另外,我知道你想每分钟运行一次。如果是这样,1 * * * *
将不会这样做。 Intead,它将运行at every 1st minute past every hour。因此,如果你想每分钟运行一次,请说* * * * *
。
了解“登录shell”和“交互式shell”意味着什么很重要。
通过OS启动shell脚本和cron作业不适合上面提到的启动shell的方式。因此,不会执行任何系统脚本(.bashrc)或用户配置文件。这意味着我们的PATH变量未初始化。无法找到Shell命令,因为PATH变量未指向正确的位置。
这解释了为什么您的脚本在手动启动时成功运行,但在通过crontab启动时失败。
解决方案-1:使用每个shell命令的绝对路径,而不是仅使用脚本文件中使用的命令名称。
解决方案-2:在执行shell脚本之前初始化环境变量,尤其是PATH变量!