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

bash script exits unexpectedly after returning from function

这是我的 关于堆栈溢出的后续问题。 我会将脚本缩减为基本部分,但如果 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 ;
 output_values;

脚本执行命令并将输出通过管道传输到我的本地函数,最终 returns 在行 echo "Last result: $result_value"; 处得到预期的结果。在此之后,它将终止提供在此函数中解析的数据的命令 - 这也有效。

当到达 return 0 时,我想应该执行脚本的下一行(命令的正下方)output_values;,但实际上没有。

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

它变得更加奇怪,因为我可以注释掉 exec 0>&- 并且所有行为都一样。一旦退出解析器函数,即使是应该由此行终止的命令也会终止。

在 returns 之后,我必须更改什么才能处理我的解析器函数的结果?这不是故意的行为。

此致

曼纽尔

让我们看看 man bash,关于 pipefail 的部分:

pipefail

If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline exit successfully. This option is disabled by default.

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

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

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

(some_command_writing_to_stdout || true) | parser