cronjob不会执行独立运行的脚本

san*_*ech 4 linux bash ubuntu crontab sh

我有我的PHP脚本文件/var/www/html/dbsync/index.php.何时cd /var/www/html/dbsync/运行php index.php它完美无缺.

我想通过sh文件调用PHP文件,SH文件的位置如下

/var/www/html/dbsync/dbsync.sh
Run Code Online (Sandbox Code Playgroud)

这是dbsync.sh文件的内容是:

/usr/bin/php /var/www/html/dbsync/index.php >> /var/www/html/dbsync/myscript.log 2>&1 -q -f
Run Code Online (Sandbox Code Playgroud)

当我cd /var/www/html/dbsync/./dbsync.sh它运行它也很完美.

现在,如果我按如下方式设置crontab:

1 * * * * /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
Run Code Online (Sandbox Code Playgroud)

但是,此crontab未按预期工作.

有什么不对?

nix*_*nix 7

了解“登录 shell”和“交互式 shell”的含义非常重要。

  • 登录 shell:当您使用 ssh 会话登录并获得一个终端窗口时,您可以在其中输入 shell 命令。登录后,系统会执行一些文件(.bashrc)并为您设置一些环境变量,例如 PATH 变量。
  • 交互式 shell :登录系统后,您可以手动启动 shell 终端。系统执行分配给您帐户的一些配置文件(.bash_profile、.bash_login、.profile)。此文件还设置一些环境变量并为手动打开的 shell 会话初始化 PATH 变量。

由操作系统启动的 shell 脚本和 cron 作业不适合上述启动 shell 的方式。因此,不会执行任何系统脚本(.bashrc)或用户配置文件。这意味着我们的 PATH 变量没有初始化。无法找到 Shell 命令,因为 PATH 变量未指向正确的位置。

这解释了为什么您的脚本在手动启动时会成功运行,但在通过 crontab 启动时会失败。

解决方案 1: 使用每个 shell 命令的绝对路径,而不仅仅是脚本文件中使用的命令名称。

  • 使用“/usr/bin/awk”代替“awk”
  • 使用“/bin/sed”代替“sed”

解决方案2:在执行shell脚本之前初始化环境变量,尤其是PATH变量!


fed*_*qui 6

如注释中所示,问题在于您没有定义应该使用哪个程序来执行脚本.考虑到cronjob是在一个微小的环境中执行的; 在那里,可以假设不多.这就是我们定义完整路径等的原因.

所以你需要说:

1 * * * * /bin/sh /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
#         ^^^^^^^
Run Code Online (Sandbox Code Playgroud)

/bin/sh 是您想要用来执行脚本的二进制文件.

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

#!/bin/sh
Run Code Online (Sandbox Code Playgroud)

如果这样做,则无需添加二进制文件的路径.

故障排除cron作业的常见问题:

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


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