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

Bash 子shell中变量函数调用分配的退出代码错误,bash,exit-code,subshell,Bash,Exit Code,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_functio

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

此代码按预期工作:

#!/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\u code
按预期为
1
,并在脚本给我
1
后运行
echo$?
(按预期)

但是,我需要获得变量和控制台输出的
my_函数的完整输出。为了做到这一点,正如本文所建议的(这似乎是基于此),我将代码更改为

#!/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
。我知道这在某种程度上与子shell处理有关,但我不知道如何解决它。

似乎

set -o pipefail
在脚本文件的开头,完成了这个技巧

现在退出代码是错误的。是0,而它应该是1吗

不,你的假设是错误的。假设
tee
成功,退出代码应为0。从:

如果保留字!不在管道之前,退出状态应为管道中指定的最后一个命令的退出状态

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

如何解决这个问题


这取决于你想要达到的行为。通常,在bash中,您可以
设置-o pipefail
以始终捕获错误。

是的,它是子shell和管道,请这样尝试

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

查看数组PIPESTATUS:
declare-p PIPESTATUS