2017-08-01 121 views
3

返回后意外这是我的last question上堆栈溢出的后续问题。 我会削减脚本的基本部分,但如果s.o.认为,知道脚本做什么可能会有所帮助,您可以查看其他问题。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; 

脚本执行命令和管道输出到我的本地函数,最后在该行echo "Last result: $result_value";,因为它是打算做返回的结果。在此之后,它将终止提供在该功能中解析的数据的命令 - 这也适用。

当达到return 0时,我想应该执行脚本的下一行(在命令的右下方)output_values;,但它不是。

即使我称之为output_values功能直接回声线前,打印的结果解析器功能,它不被执行。

它会变得更加怪异,因为我可以注释掉exec 0>&-和所有行为一样。即使应该由该行终止的命令也会在解析器函数退出时立即终止。

我有什么改变能够与我的解析器函数的结果上下工夫,它返回后?这不能是有意的行为。

问候

曼努埃尔

+0

后的样本代码很简单,工作并产生准确的故障 – Anubis

+0

你尝试'设置-x'? –

+0

'set -x'只显示'return 0'后面的退出,之后没有执行任何操作。 –

回答

4

让我们来看看man bash,节上pipefail

pipefail

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

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

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

很容易验证这一点。只需更换与倒数第二个声明:

(some_command_writing_to_stdout || true) | parser $2 
+0

你是绝对正确的。我注释掉pipefail选项,它工作。不过,我希望能得到有关退出代码的信息!= 0是使用'set -x'时立即退出脚本的原因。 –

+0

你没有得到'some_command_writing_to_stdout'的退出代码吗? – randomir

+0

脚本输出它从解析管道标准输出数据和“最后结果”行中获得的值。使用'set -x'不能提供比正在执行的最后一行更多的信息是'return 0'。 –