我有一个执行多个文件操作的 bash 脚本。当任何用户运行此脚本时,它都会成功执行并输出几行文本,但是当我尝试 cron 时会出现问题。它似乎正在运行(我在 cron 日志中看到一个条目显示它已被启动)但没有任何反应,它不输出任何内容并且不执行任何文件操作。它也不会出现在任何地方的正在运行的进程中,因此它似乎会立即退出。
经过一些故障排除后,我发现删除“set -e”解决了这个问题,它现在可以从系统 cron 运行而没有问题。所以它可以工作,但我宁愿启用 set -e 以便脚本在出现错误时退出。有谁知道为什么“set -e”导致我的脚本退出?
感谢您的帮助,
瑞安
2 回答
当您的脚本在 cron 下运行时,环境变量和路径的设置可能与脚本由用户直接运行时不同。也许这就是它表现不同的原因?
要对此进行测试:创建一个新脚本,它只执行printenv
and echo $PATH
。手动运行此脚本,保存输出,然后将其作为 cron 作业运行,保存该输出。比较两种环境。我相信您会发现差异...交互式登录 shell 将通过采购“.login”、“.bash_profile”或类似脚本(取决于用户的 shell)来设置其环境。这通常不会在 cron 作业中发生,这通常是 cron 作业的行为与在登录 shell 中运行相同脚本不同的原因。
要解决此问题:在脚本顶部,显式设置环境变量和 PATH 以匹配交互式环境,或者获取用户的“.bash_profile”、“.login”或其他设置脚本,具体取决于他们使用的 shell重新使用。
使用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
)以在执行命令时显示命令。