子 shell 中变量函数调用分配的错误退出代码

Wrong exit code for variable function call assignment in subshell

我有一个经常失败的脚本。传递正确的退出代码至关重要。

此代码按预期工作:

#!/usr/bin/env bash

function my_function {
    echo "Important output"
    exit 1
}

function cleanup {
  MY_EXIT_CODE=$?
  echo "MY_EXIT_CODE: ${MY_EXIT_CODE}"
}

trap cleanup EXIT

my_function

MY_EXIT_CODE 是预期的 1 和 运行 echo $? 在脚本给我 1 之后(如预期的那样)

但是,我需要将 my_function 的完整输出同时输出到变量和控制台输出。为此,按照 (which seems itself based on this answer) 中的建议,我将代码更改为

#!/usr/bin/env bash

function my_function {
    echo "Important output"
    exit 1
}

function cleanup {
  MY_EXIT_CODE=$?
  echo "MY_EXIT_CODE: ${MY_EXIT_CODE}"
}

trap cleanup EXIT

exec 5>&1
FF=$(my_function|tee /dev/fd/5)

现在退出代码是错误的。是 0 而应该是 1。我知道这在某种程度上与 subshel​​l 处理有关,但我不知道如何解决它。

好像只是说

set -o pipefail

在脚本文件的开头就成功了。

And now the exit code is wrong. Is it 0 while it should be 1

不,你的假设是错误的。假设 tee 成功,退出代码应为 0。来自 posix shell manual:

If the reserved word ! does not precede the pipeline, the exit status shall be the exit status of the last command specified in the pipeline.

管道中的“最后一个命令”是最右边的命令。因为在您的情况下 tee 以 0 退出,所以 FF=$(.... | tee) 的退出状态为零。

how to solve it.

这取决于您想要实现的行为。通常,在 bash 中,您可能只是 set -o pipefail 总是捕获错误。

是的,它是子外壳和管道,这样试试

FF=$(my_function|tee /dev/fd/5; exit $PIPESTATUS)