bash cronjob 不执行独立运行的脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36885909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
cronjob does not execute a script that works fine standalone
提问by sanainfotech
I have my php script file in /var/www/html/dbsync/index.php
. When cd /var/www/html/dbsync/
and run php index.php
it works perfectly.
我在 .php 中有我的 php 脚本文件/var/www/html/dbsync/index.php
。何时cd /var/www/html/dbsync/
运行php index.php
它完美无缺。
I want to call PHP file through sh file, the location of SH file is as below
我想通过sh文件调用PHP文件,SH文件的位置如下
/var/www/html/dbsync/dbsync.sh
This is the content of the dbsync.sh
file is:
这是dbsync.sh
文件的内容是:
/usr/bin/php /var/www/html/dbsync/index.php >> /var/www/html/dbsync/myscript.log 2>&1 -q -f
When I cd /var/www/html/dbsync/
and run ./dbsync.sh
it works perfectly as well.
当我cd /var/www/html/dbsync/
运行./dbsync.sh
它时,它也能完美运行。
Now if I set up crontab as below:
现在,如果我设置 crontab 如下:
1 * * * * /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
However, this crontab is not working as expected.
但是,这个 crontab 没有按预期工作。
What can be wrong?
有什么问题?
回答by fedorqui 'SO stop harming'
As seen in comments, the problem is that you are not defining what program should be used to execute the script. Take into account that a cronjob is executed in a tiny environment; there, not much can be assumed. This is why we define full paths, etc.
正如评论中所见,问题在于您没有定义应该使用什么程序来执行脚本。考虑到 cronjob 是在一个很小的环境中执行的;在那里,不能假设太多。这就是我们定义完整路径等的原因。
So you need to say something like:
所以你需要这样说:
1 * * * * /bin/sh /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
# ^^^^^^^
/bin/sh
being the binary you want to use to execute the script.
/bin/sh
是您要用于执行脚本的二进制文件。
Otherwise, you can set execution permissions to the script and add a shell-script headertelling it what interpreter to use:
否则,您可以为脚本设置执行权限并添加一个shell-script 标头,告诉它使用什么解释器:
#!/bin/sh
If you do this, adding the path of the binary is not necessary.
如果这样做,则不需要添加二进制文件的路径。
From Troubleshooting common issues with cron jobs:
Using relative paths. If your cron job is executing a script of some kind, you must be sure to use only absolute paths inside that script. For example, if your script is located at /path/to/script.phpand you're trying to open a file called file.php in the same directory, you cannot use a relative path such as fopen(file.php). The file must be called from its absolute path, like this: fopen(/path/to/file.php). This is because cron jobs do not necessarily run from the directory in which the script is located, so all paths must be called specifically.
使用相对路径。如果您的 cron 作业正在执行某种脚本,您必须确保仅在该脚本中使用绝对路径。例如,如果您的脚本位于 /path/to/script.php 并且您尝试打开同一目录中名为 file.php 的文件,则不能使用诸如 fopen(file.php) 之类的相对路径。该文件必须从其绝对路径调用,如下所示:fopen(/path/to/file.php)。这是因为 cron 作业不一定从脚本所在的目录运行,因此必须专门调用所有路径。
Also, I understand you want to run this every minute. If so, 1 * * * *
won't do. Intead, it will run at every 1st minute past every hour. So if you want to run it every minute, say * * * * *
.
另外,我知道您想每分钟运行一次。如果是这样,1 * * * *
不会。Intead,它将在每小时过去的每 1 分钟运行一次。因此,如果您想每分钟运行一次,请说* * * * *
.
回答by nix
It is important to understand "login shell" and "interactive shell" what they means.
了解“登录外壳”和“交互式外壳”的含义很重要。
- login shell: is briefly when you sign in with ssh session and get a terminal window where you can enter shell commands. After login the system executes some files(.bashrc) and sets some environment variables such as the PATH variable for you.
- interactive shell :After login on a system, you can startup manually shell terminal(s). The system executes some profile file assigned to your account (.bash_profile, .bash_login,.profile). This files also sets some environment variables and initialize PATH variable for your manually opened shell session.
- 登录 shell:当您使用 ssh 会话登录并获得一个终端窗口时,您可以在其中输入 shell 命令。登录后,系统会执行一些文件(.bashrc)并为您设置一些环境变量,例如 PATH 变量。
- 交互式shell:登录系统后,您可以手动启动shell终端。系统会执行一些分配给您帐户的配置文件(.bash_profile、.bash_login、.profile)。此文件还为您手动打开的 shell 会话设置一些环境变量并初始化 PATH 变量。
By OS started shell scripts and cron jobs does not fit in above mentioned way for starting a shell. Therefore no any system scripts(.bashrc) or user profiles are executed. This means our PATH variable is not initialized. Shell commands could not found because PATH variable does not point to right places.
由操作系统启动的 shell 脚本和 cron 作业不适合上述启动 shell 的方式。因此不会执行任何系统脚本 (.bashrc) 或用户配置文件。这意味着我们的 PATH 变量没有被初始化。找不到 Shell 命令,因为 PATH 变量没有指向正确的位置。
This explains why your script runs successfully if you start it manually but fails when you start it via crontab.
这解释了为什么您的脚本在您手动启动时成功运行但在您通过 crontab 启动时失败的原因。
Solution-1:Use absolute path of every shell command instead of only the command name used in your script file(s).
解决方案 1:使用每个 shell 命令的绝对路径,而不仅仅是脚本文件中使用的命令名称。
- instead of "awk" use "/usr/bin/awk"
- instead of "sed" use "/bin/sed"
- 使用“/usr/bin/awk”代替“awk”
- 使用“/bin/sed”代替“sed”
Solution-2:Initialize environment variables and especially the PATH variable before executing shell scripts!
解决方案 2:在执行 shell 脚本之前初始化环境变量,尤其是 PATH 变量!