如果反引号运算符失败,如何打印并退出 bash

如果反引号运算符失败,如何打印并退出 bash

我有getinfo.sh它要么打印信息,要么以代码 1 存在。

我想将此脚本的结果存储在 bash 变量中,否则打印错误消息并退出。

如果我运行这个

#!/bin/bash
X=`getinfo.sh` || echo "failed" && exit 1

那么即使成功,脚本也会退出getinfo.sh(在这种情况下,它什么也不打印。

另一方面

X=`getinfo.sh` || (echo "failed" && exit 1)

对于我来说,这是有道理的,因为我来自类似 C 语言的语言,但是不是退出脚本,因为括号创建了一个新的内壳,并且退出的是内壳,外壳继续运行。

如果失败,如何存储getinfo.sh打印并退出的输出?

答案1

(...)不是(主要)团体命令,而是启动一个子 shell。所以exitin(echo failed && exit 1)只退出子 shell。

要对命令进行分组而不在子 shell 中运行它们,您可以使用{ ...; }

X=`getinfo.sh` || {
  echo >&2 "failed"
  exit 1
}

虽然在这里,我宁愿使用:

if ! x=$(getinfo.sh); then
  echo >&2 failed
  exit 1
fi

另请注意,echo failed && exit 1如果本身失败,则可能无法退出echo,例如,当 stdout 是完整文件系统上的文件时,或者忽略 SIGPIPE 的损坏管道,或者 stdout 已关闭,或者已达到 SIGXFSZ 的文件大小限制时,可能会发生这种情况忽略...

答案2

您可以使用大括号将命令组合在一起,而无需创建子 shell。

X=$(getinfo.sh) || { echo "failed" && exit 1; }

分组命令Bash 手册中的部分

{ list; }

将命令列表放在大括号之间会导致该列表在当前 shell 上下文中执行。没有创建子shell。后面的分号(或换行符)列表是必须的。

注意:对于命令替换,反引号实际上已被弃用,因此我使用了更现代的$()语法。

答案3

既然您正在设置变量的值,为什么不检查变量的值并在不合适时退出呢?

X=`getinfo.sh`

[ -z "$X" ] && echo "failed" && exit 1

这假设getinfo.sh失败时返回空(如果长度为零,则退出),但您可以根据失败时返回的X内容修改检查。getinfo或者更恰当地说,检查以确保X包含您正在查找的数据类型。

答案4

最简单的方法是将 -e 添加到你的 shebang 中:

#!/bin/bash -e

这意味着脚本将在出现第一个错误时停止。由于您使用反引号,因此如果有任何错误消息,您可能会在标准输出中看到它。

如果您确实想使用 echo-and-exit 方法,我会编写一个单独的函数来调用,它总是打印一些错误消息并立即退出。了解如何编写 bash 函数(它们非常简单)。

相关内容