3

This is a follow up question to my last question on stack overflow. I'll cut down the script to the essential parts, but if s.o. thinks, it might be helpful to know what the script does, you may look into the other question.

 #!/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;

The script executes the command and pipes the output to my local function which finally returns a result at the line echo "Last result: $result_value"; as it is intended to do. After this, it shall terminate the command that provides the data which is parsed in this function - this works, too.

When reaching return 0, I'd think, the next line of the script (right below of the command) output_values; should be executed, but it is not.

Even if I call the output_values function directly before the echo line, that prints the result in the parser function, it is not executed.

It gets even more weird, as I can comment out exec 0>&- and all behaves just the same. Even the command that should be terminated by this line, gets terminated, as soon as the parser function is being exited.

What do I have to change to be able to work on with the results of my parser function, after it returns? This can't be intended behavior.

Regards

Manuel

3
  • post a sample code which is simple, working and produce the exact failure Commented Aug 1, 2017 at 13:39
  • Did you try set -x? Commented Aug 1, 2017 at 13:39
  • set -x just shows the exiting after return 0 and nothing is being executed afterwards. Commented Aug 1, 2017 at 13:45

1 Answer 1

5

Let's have a look at man bash, section on 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.

Combined with set -e, which will exit whenever a command (pipeline) exits with non-zero exit status, the only logical conclusion is: your some_command_writing_to_stdout must be exiting with a non-zero exit status (because evidently, parser exist with 0).

This would explain why the next command in the pipeline (parser) get executed, and why your script finishes after that.

It's easy enough to verify this. Just replace the penultimate statement with:

(some_command_writing_to_stdout || true) | parser $2
Sign up to request clarification or add additional context in comments.

4 Comments

You are absolutely correct. I commented out the pipefail option and it works. I would have expected to get information about the exit code != 0 being the cause for immediate exiting of the script when using set -x, though.
Are you not getting the exit code for some_command_writing_to_stdout?
The script outputs the values it obtains from parsing the piped stdout data and the "last result" line. Using set -xdoes not provide more information than the last line being executed is return 0.
I was guessing your some_command_writing_to_stdout might be a function (then you would see the return statement last executed), but if it's a command, you're right, you won't be able to see the exit status with set -x. Which is unfortunate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.