从命令行 bash 运行时,无法从 crontab 运行 bash 脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26531098/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 11:37:54  来源:igfitidea点击:

Cannot run bash script from crontab when it works from command line bash

bashcroncrontab

提问by kal

I have a strange problem of being to able to run a bash script from commandline but not from the crontab entry for root. I am running Ubuntu 12.04.

我有一个奇怪的问题,即能够从命令行运行 bash 脚本,但不能从 root 的 crontab 条目运行。我正在运行 Ubuntu 12.04。

* * * * 1-5 root /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log

If I run the script from the cmd line using bash, it works fine but shfails with following error:

如果我使用 bash 从 cmd 行运行脚本,它工作正常但sh失败并出现以下错误:

> jmeter-cron-randomise.sh: 7: jmeter-cron-randomise.sh: arithmetic
> expression: expecting primary: "  % 1 "

Having googled the problem, it seems like standard shell doesn't have the same math operators, like % (modulus), as bash. I'm Not sure why the cron job is failing in the script? I am assuming it is because it's not using the bash shell? It's definitely being fired by the cron daemon (can see it in /var/log/syslog). Any help much appreciated.

用谷歌搜索这个问题后,似乎标准 shell 没有与 bash 相同的数学运算符,如 %(模数)。我不确定为什么脚本中的 cron 作业失败?我假设这是因为它没有使用 bash shell?它肯定是由 cron 守护进程触发的(可以在 /var/log/syslog 中看到它)。非常感谢任何帮助。

回答by Reid Spencer

You likely need to tell cron that the shell to use is the bash shell as it defaults to sh. You can do that for all crontab entries by putting this line in your crontab:

您可能需要告诉 cron 要使用的 shell 是 bash shell,因为它默认为 sh。您可以通过将此行放在您的 crontab 中来为所有 crontab 条目执行此操作:

SHELL=/bin/bash

Note that this will cause all scripts in the crontab to be run under bash which may not be what you want. If you want to change the crontab line itself to just run bash, change it to this:

请注意,这将导致 crontab 中的所有脚本都在 bash 下运行,这可能不是您想要的。如果您想将 crontab 行本身更改为仅运行 bash,请将其更改为:

* * * * 1-5 root /bin/bash /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log 2>&1

Note that I have also caused stderr to be written to the cron.log file (2>&1) which may not be what you want but is pretty common practice. This may help you further diagnose errors from the script.

请注意,我还导致将 stderr 写入 cron.log 文件 (2>&1),这可能不是您想要的,但很常见。这可以帮助您进一步诊断脚本中的错误。

回答by olliehaffenden

In case this helps anyone: for me this appeared to be because I had ended up with "DOS" line endings(CR-LF) instead of "unix" line endings (LF). This can be checked using odor your favourite hex dump tool, e.g.:

万一这对任何人都有帮助:对我来说,这似乎是因为我最终得到了“DOS”行结尾(CR-LF)而不是“unix”行结尾(LF)。这可以使用od或您最喜欢的十六进制转储工具进行检查,例如:

od -c <script_file>

... and look for \r\n instead of just \n.

... 并寻找 \r\n 而不仅仅是 \n。

It seems (and this articlesupports it) that the CR character stops the "shebang" from working because it's interpreted as part of the shell executable's filename.

似乎(并且本文支持它)CR 字符会阻止“shebang”工作,因为它被解释为 shell 可执行文件的文件名的一部分。

(The line endings themselves appeared because the file came from a git repository and was transferred via a Windows machine).

(出现行尾是因为该文件来自 git 存储库并通过 Windows 机器传输)。