这是关于堆栈溢出的last question的后续问题。 我会将脚本缩减为基本部分,但如果是s.o.认为,了解脚本的功能可能会有所帮助,您可以查看另一个问题。
#!/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;
脚本执行命令并将输出传递给我的本地函数,该函数最终在行echo "Last result: $result_value";
处返回结果。在此之后,它将终止提供在此函数中解析的数据的命令 - 这也有效。
到达return 0
时,我认为,应该执行脚本的下一行(命令正下方)output_values;
,但事实并非如此。
即使我在echo行之前直接调用output_values函数,它在解析器函数中打印结果,也不会执行。
它变得更加奇怪,因为我可以注释掉exec 0>&-
并且所有行为都是一样的。一旦解析器函数退出,即使是该行终止的命令也会终止。
在返回之后,我需要更改哪些能够处理我的解析器函数的结果?这不是预期的行为。
此致
曼努埃尔
答案 0 :(得分:4)
让我们看一下man bash
上的pipefail
部分:
<强>
pipefail
强>如果设置,管道的返回值是以非零状态退出的最后(最右边)命令的值,如果管道中的所有命令都成功退出,则返回零。默认情况下禁用此选项。
结合set -e
,只要命令(管道)以非零退出状态退出,它就会退出,唯一合乎逻辑的结论是:
您的some_command_writing_to_stdout
必须以非零退出状态退出(因为显然parser
存在0
)。
这可以解释为什么管道中的下一个命令(parser
)会被执行,以及为什么脚本在此之后完成。
验证这一点很容易。只需将倒数第二个语句替换为:
(some_command_writing_to_stdout || true) | parser $2