![在 cron 中使用 BASH 的问题(FreeBSD)](https://linux22.com/image/552425/%E5%9C%A8%20cron%20%E4%B8%AD%E4%BD%BF%E7%94%A8%20BASH%20%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%88FreeBSD%EF%BC%89.png)
场景:我们有一个运行 FreeBSD 4.7 的旧系统(请不要笑。它将在年底退役。我只需要让它继续运行并备份到那时),并且我有一些数据库转储脚本,我每天使用 cron 作业运行它们。我以 #!/usr/local/bin/bash 开头脚本。该脚本使用 date 命令将日期作为转储文件的文件名的一部分。当我手动运行脚本时,它会按预期工作。但是,当我将其放入 cron 作业时,它会失败。我检查了错误日志,它在脚本中使用反引号和 date 命令作为文件名的部分失败(我也在文件名中尝试了 $(date...),但出现了相同的错误。因此,我尝试在 cron 作业中添加 /usr/local/bin/bash /path/to/script.sh,但仍然出现相同的错误。
所以我的猜测是它在运行时没有切换到 bash shell。我首先想到在脚本中添加 echo $SHELL 来查看,但我发现切换 shell 实际上并没有切换 SHELL 变量的值。
有没有人遇到过类似的 FreeBSD 问题?或者有没有人知道我可以检查它在执行时使用哪个 shell 的替代方法?(我也尝试过 ps >> test.txt,但在 cron 中也不起作用)。
答案1
当我读到这篇文章时,我想到了一些事情。
如果您正在运行 bash,则 $BASH 的值应该扩展为正在使用的 bash 可执行文件的完整路径和文件名。
您如何在脚本中调用 date。您是使用完整路径名还是以“date”的形式调用它。后一种情况可能会导致使用函数、别名或路径中第一个出现的任何内容,而不是您期望的 date 程序。
在某些情况下,Bash 的行为会有所不同,具体取决于环境。您可能希望将环境从脚本转储到文件中,然后从命令行和 cron 查看它的运行情况。您可能会发现 PATH 不同,或者其他一些环境变量的设置不同。您应该能够通过在脚本中放入一行类似“env > /tmp/environment.$$”来将其转储到 /tmp 中的文件中。每次运行脚本时,它都会将环境打印到名为 environment.(脚本的 pid) 的文件中
您还可以通过在一行中使用“SHELL=/path/to/new/shell”将整个 crontab 的 shell 设置为您想要的任何 shell。
答案2
尝试明确设置环境变量(例如PATH
)或明确获取启动文件(例如/etc/profile
或/home/root/.profile
或其他)。
如果您cron
假设使用另一个 shell,您可能需要exec
bash 脚本。
答案3
至少某些版本的 cron 将“%”解释为特殊字符。我无法从上面的回答中判断您是否在 crontab 本身中使用了该 date 命令。请参阅您的手册页。它是
man 5 crontab
另一个 crontab 手册页是关于 crontab 命令的,而不是文件的格式。
在 Linux 上但我不确定在 BSD 上。
如果是这种情况,您可以通过在 % 前面加上 \ 来转义该 % 来修复它。