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
source to share
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
source to share