bash脚本从函数返回后意外退出

这是关于堆栈溢出的最后一个问题的跟进问题。 我会把脚本删减到基本部分,但是如果这样做的话,可能会有助于知道脚本的作用,你可以看看另一个问题。

#!/usr/bin/env bash set -eu -o pipefail declare -a framelist #Print all results function output_values() { echo "Results!"; } #parsing information from stdin function parser () { while read tc; do if [ -z "$tc" ]; then continue fi #Evaluation and saving result to array echo $result_value; framelist+=($result_value); if (( <<some abort condition>> )); then exec 0>&- echo "Last result: $result_value"; return 0 fi done } some_command_writing_to_stdout | parser $2; output_values; 

脚本执行命令,并将输出pipe道输出到我的本地函数,最终返回结果在行echo "Last result: $result_value"; 正如它打算这样做。 之后,它将终止提供在这个函数中被parsing的数据的命令 – 这也是有效的。

当达到return 0 ,我想,脚本的下一行(在命令的下面) output_values; 应该被执行,但事实并非如此。

即使我直接在echo线之前调用output_values函数,它将结果打印到parsing器函数中,也不会执行。

它变得更奇怪了,因为我可以评论exec 0>&-所有行为都是一样的。 即使是应该由该行终止的命令,只要parsing器函数正在退出,终止。

我需要改变什么才能使用我的分析器函数的结果,它返回后? 这不能是有意的行为。

问候

曼努埃尔

让我们来看看man bash ,关于pipefail一节:

pipefail

如果设置,管道的返回值是以非零状态退出的最后(最右边)命令的值 ,如果管道中的所有命令均成功退出,则为零。 该选项默认是禁用的。

结合set -e ,只要命令(管道)以非零退出状态退出,就会退出,唯一合乎逻辑的结论是: 你的some_command_writing_to_stdout必须以非零退出状态退出 (因为显然, parser0存在) 。

这将解释为什么管道( parser )中的下一个命令得到执行,以及为什么你的脚本完成后。

验证这一点很简单。 只需将倒数第二个语句替换为:

 (some_command_writing_to_stdout || true) | parser $2