【问题标题】:`shopt -s inherit_errexit` has no effect in declare command [duplicate]`shopt -s inherit_errexit`在声明命令中无效[重复]
【发布时间】:2025-12-03 17:20:10
【问题描述】:
#!/bin/bash
set -e
set -o pipefail
shopt -s inherit_errexit

declare _x=`command-with-error`
echo "_x=${_x}"

运行脚本显示:

bash xx.sh
xx.sh: line 6: command-with-error: command not found
_x=

显然第 6 行没有退出 shell。当 declare 行上的 subshel​​l 命令失败时,我应该使用什么选项使脚本退出?

【问题讨论】:

  • 我假设您已经阅读了BashFAQ #105errexit 的行为在各个 shell 版本之间有很大的不同,更不用说在不同的 shell 之间,甚至在不同的调用上下文中(set -e 根据函数本身的退出状态 或任何东西来改变函数中代码的行为else 在调用堆栈中向上分支);很难审核代码的正确性,这比简单审核显式错误处理要困难得多(例如在每个单独的命令之后添加|| exit|| return)。
  • 在特定情况下,declare _x=$(anything) 是一种反模式。使declare _x 成为一个命令,_x=$(anything) 成为第二个命令。 localtypeset 也是如此。
  • 我建议您使用 shellcheck.net 检查您的脚本,它会指出您遇到此问题的原因:SC2155 Declare and assign separately to avoid masking return values.

标签: bash


【解决方案1】:

declare 的成功退出状态覆盖了command-with-error 的不成功退出状态。

将其分解为两个单独的命令:

declare _x
_x=$(command-with-error)

...您可以在https://ideone.com/TGyFCZ看到正确运行(也就是说,无需向标准输出写入任何内容)

【讨论】: