【问题标题】:Why does using set -e cause my script to fail when called in crontab?为什么在 crontab 中调用时使用 set -e 会导致我的脚本失败?
【发布时间】:2011-02-21 15:27:51
【问题描述】:

我有一个执行多个文件操作的 bash 脚本。当任何用户运行此脚本时,它都会成功执行并输出几行文本,但是当我尝试 cron 时,它会出现问题。它似乎正在运行(我在 cron 日志中看到一个条目显示它已被启动)但没有任何反应,它不输出任何内容并且不执行任何文件操作。它也不会出现在任何地方的正在运行的进程中,因此它似乎会立即退出。

经过一些故障排除后,我发现删除“set -e”解决了这个问题,它现在可以从系统 cron 运行而没有问题。所以它可以工作,但我宁愿启用 set -e 以便脚本在出现错误时退出。有谁知道为什么“set -e”导致我的脚本退出?

感谢您的帮助,
瑞恩

【问题讨论】:

  • 如果set -e 导致它在出错时退出......那不是意味着某处有错误吗?
  • 如果我手动运行脚本就会执行。另外,如果遇到任何问题,应在退出前将错误代码打印到标准输出。这不会发生。
  • 除非您展示您的脚本,否则我们无法判断问题所在。另外,在我看来,set -e 不能替代正确的错误处理,根本不应该使用。
  • @MitchDempsey, ...对于set -e 目的而言,什么是“错误”和一个理性人头脑中的错误不一定是一回事。看看BashFAQ #105 中的练习有多少你做对了。

标签: bash scripting crontab


【解决方案1】:

当您的脚本在 cron 下运行时,环境变量和路径的设置可能与脚本由用户直接运行时不同。也许这就是它表现不同的原因?

要对此进行测试:创建一个除了printenv 和echo $PATH 之外什么都不做的新脚本。 手动运行此脚本,保存输出,然后将其作为 cron 作业运行,保存该输出。 比较两种环境。我相信你会发现不同之处......一个互动 login shell 将通过采购“.login”、“.bash_profile”、 或类似的脚本(取决于用户的外壳)。这一般不会发生在 cron 作业,这通常是 cron 作业的行为与运行不同的原因 登录 shell 中的相同脚本。

要解决这个问题:在脚本顶部,显式设置环境变量 和 PATH 匹配交互环境,或者来源用户的“.bash_profile”, “.login”或其他设置脚本,具体取决于他们使用的 shell。

【讨论】:

  • 我同意吉姆。除了 cron 以用户身份运行之外,我可以手动启动脚本而不会出现问题。让我们称它为 user1 ...生成。如果我从脚本顶部删除“set -e”,它会从 cron 正常运行,尽管标准脚本输出显示,但 stdout 或 stderr 没有错误。我完全被这件事难住了......
  • @SDGuero:我已经扩展了我对可能发生的情况的解释,并提供了一些额外的故障排除建议。希望这会有所帮助。
【解决方案2】:

使用set -e,脚本将在第一个给出非零退出状态的命令处停止。这并不一定意味着您会看到错误消息。

这里是一个示例,使用false 命令,该命令除了以错误状态退出之外什么都不做。

没有set -e:

$ cat test.sh
#!/bin/sh

false
echo Hello

$ ./test.sh
Hello
$

但是带有set -e 的相同脚本会退出而不打印任何内容:

$ cat test2.sh
#!/bin/sh

set -e

false
echo Hello

$ ./test2.sh
$ 

根据您的观察,听起来您的脚本在生成任何输出之前由于某种原因(可能与 Jim Lewis 建议的不同环境有关)失败了。

要进行调试,请将set -x 添加到脚本顶部(以及set -e)以在执行命令时显示命令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多