Linux bash脚本从函数返回后意外退出
这是我关于堆栈溢出的后续问题。 我将把脚本缩减到基本部分,但如果s.o.认为,了解脚本的作用可能会有所帮助,您可以研究另一个问题Linux bash脚本从函数返回后意外退出,linux,bash,shell,stdout,execution,Linux,Bash,Shell,Stdout,Execution,这是我关于堆栈溢出的后续问题。 我将把脚本缩减到基本部分,但如果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 p
#!/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;
#/usr/bin/env bash
set-eu-o管道故障
声明-框架列表
#打印所有结果
函数输出_值(){
回应“结果!”;
}
#从stdin解析信息
函数分析器(){
读tc时;
做
如果[-z“$tc”];则
持续
fi
#求值并将结果保存到数组
echo$result\u值;
框架列表+=($result\u值);
如果(());那么
执行0>&-
回显“最后结果:$result_值”;
返回0
fi
完成
}
一些命令写入到解析器$2;
输出_值;
脚本执行命令并将输出传输到my local函数,该函数最终在echo“Last result:$result_value”行返回一个结果代码>按预期执行。在此之后,它将终止提供在此函数中解析的数据的命令-这也起作用
当到达返回0
时,我认为,脚本的下一行(命令的右下方)输出\u值应该执行代码>,但不是
即使我直接在echo行之前调用output_values函数(它在解析器函数中打印结果),它也不会执行
它变得更加奇怪,因为我可以注释掉exec 0>&-
,所有的行为都是一样的。甚至应该由此行终止的命令也会在解析器函数退出时终止
在解析器函数返回后,为了处理解析器函数的结果,我必须做哪些更改?这不是故意的行为
问候
Manuel让我们看看man bash
,pipefail
一节:
pipefail
如果设置,管道的返回值是最后一个(最右边)以非零状态退出的命令的值,如果管道中的所有命令都成功退出,则返回值为零。默认情况下,此选项处于禁用状态
结合set-e
,只要命令(管道)以非零退出状态退出,它就会退出,唯一的逻辑结论是:
您的某些命令\u写入到\u stdout
必须以非零退出状态退出(因为显然,解析器
存在于0
)
这将解释为什么管道中的下一个命令(parser
)会被执行,以及为什么脚本会在执行之后完成
验证这一点很容易。只需将倒数第二个语句替换为:
(some_command_writing_to_stdout || true) | parser $2
发布一个简单、有效且产生确切故障的示例代码您是否尝试过set-x
?set-x
仅显示退出后返回0
,之后没有执行任何操作。您完全正确。我注释掉了pipefail选项,它可以工作。我本来希望得到关于出口代码的信息!=但是,0是使用set-x
时立即退出脚本的原因。您是否未获得某些命令写入到\u stdout
的退出代码?脚本将输出它从分析管道化stdout数据和“last result”行获得的值。使用set-x
不会提供比执行的最后一行是return 0
更多的信息。我猜您的某些命令写入到stdout
可能是一个函数(然后您会看到上次执行的return
语句),但如果它是一个命令,您是对的,您将无法使用set-x
查看退出状态。这是不幸的。