Bash script exits unexpectedly after returning from function
This is the next question to my last Stack Overflow question . I'll shorten the script to the parts needed, but if so thinks it might be helpful to know what the script is doing, you might want to look into another 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 outputs the result to my local function, which finally returns the result in string echo "Last result: $result_value";
as it is supposed to. After that, it must complete the command that provides the data that is analyzed in this function - this also works.
Upon reaching return 0
, I think the following script line (to the right of the command) output_values;
should be executed, but it is not.
Even if I call the output_values function just before the echo line that prints the result in the parser function, it fails.
It gets even weirder as I can comment exec 0>&-
and everything behaves exactly the same. Even the command that needs to be terminated with this line is completed as soon as the parser function exits.
What do I need to change to work with the results of my parser function after it returns? This may not be the intended behavior.
Hello
Manuel
Let's look at man bash
, section on pipefail
:
pipefail
If set, the return value of the pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline successfully completed. This option is disabled by default.
Combined with set -e
, which will exit whenever a command (pipeline) exits with a non-zero exit status, the only logical conclusion is:
yours some_command_writing_to_stdout
should exit with a non-zero exit status (because obviously parser
there is with 0
).
This explains why the next command in the pipeline ( parser
) is executed , and why your script ends after that.
It is easy enough to check this. Just replace the penultimate statement:
(some_command_writing_to_stdout || true) | parser $2