从函数

时间:2017-08-01 13:28:08

标签: linux bash shell stdout execution

这是关于堆栈溢出的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>&-并且所有行为都是一样的。一旦解析器函数退出,即使是该行终止的命令也会终止。

在返回之后,我需要更改哪些能够处理我的解析器函数的结果?这不是预期的行为。

此致

曼努埃尔

1 个答案:

答案 0 :(得分:4)

让我们看一下man bash上的pipefail部分:

  

<强> pipefail

     

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

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

这可以解释为什么管道中的下一个命令(parser)会被执行,以及为什么脚本在此之后完成。

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

(some_command_writing_to_stdout || true) | parser $2