cronjob不执行独立工作的脚本

我有我的PHP脚本文件在/var/www/html/dbsync/index.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是在微小的环境中执行的; 那里,可以假设不多。 这就是我们定义完整path的原因

所以你需要这样说:

 1 * * * * /bin/sh /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync # ^^^^^^^ 

/bin/sh是你想用来执行脚本的二进制文件。

否则,您可以为脚本设置执行权限,并添加一个shell脚本头,告诉它使用什么解释器:

 #!/bin/sh 

如果你这样做,添加二进制文件的path是没有必要的。

解决与cron作业有关的常见问题 :

使用相对path。 如果您的cron作业正在执行某种脚本,则必须确保在该脚本中只使用绝对path。 例如,如果您的脚本位于/path/to/script.phpand中,您正试图在同一个目录中打开一个名为file.php的文件,则不能使用诸如fopen(file.php)之类的相对path。 该文件必须从其绝对path调用,如下所示:fopen(/path/to/file.php)。 这是因为cron作业不一定从脚本所在的目录运行,所以必须专门调用所有path。


另外,我知道你想每分钟运行一次。 如果是这样, 1 * * * *将不会。 Intead,它将在每小时过去的每一分钟运行。 所以如果你想每分钟运行一次,就说* * * * *

理解“loginshell”和“交互式shell”是什么意思是很重要的。

  • loginshell:简单地用ssh会话login并获得一个terminal窗口,您可以在其中inputshell命令。 login后,系统执行一些文件(.bashrc),并为您设置一些环境variables,如PATHvariables。
  • 交互式shell:login系统后,可以手动启动shellterminal。 系统执行一些分配给您帐户的configuration文件(.bash_profile,.bash_login,.profile)。 这些文件还设置了一些环境variables,并为您手动打开的shell会话初始化PATHvariables。

通过操作系统启动shell脚本和cron作业不符合上述方式启动一个shell。 因此,不会执行任何系统脚本(.bashrc)或用户configuration文件。 这意味着我们的PATHvariables没有被初始化。 Shell命令找不到,因为PATHvariables没有指向正确的位置。

这就解释了为什么你的脚本运行成功,如果你手动启动,当你通过crontab启动时失败。

解决scheme1:使用每个shell命令的绝对path,而不是只使用脚本文件中使用的命令名称。

  • 而不是“awk”使用/ usr / bin / awk
  • 而不是“sed”使用“/ bin / sed”

解决scheme2:在执行shell脚本之前初始化环境variables,尤其是PATHvariables!