I am writing a shell script which must run a series of commands, some using Python scripts, in a for loop. As this script is expected to take a long amount of time to finish executing, and it is important to retain the output of different commands in a file for inspection, I have used tee to direct output to a file and terminal. Additionally, it is possible some commands could fail on certain iterations, so I wish to have a || continue statement after these to skip to the next iteration.
I cannot seem to find a way to skip to the next iteration with || continue and keep the useful behaviour of tee. How can I do this?
An illustrative example of my code is, with a function that should fail and how I wish to execute it in a for loop:
#!/bin/bash
set -e
some_failing_func(){
var=$1
if [ $var == 5 ]; then
return 0
else
echo "Failed, value not 5"
return 1
fi
}
main(){
log_file=$1
for i in {0..10}; do
# I really want to record 'failed' and continue to next iteration
some_failing_func 1 2>&1 | tee "$log_file" -a || continue
done
}
main "$1"
The continue behaviour does work as expected if I remove tee. I have tried to change the -p option to warn and exit, but this did not appear to work.I also removed 2>&1, and this didn't resolve it. Additionally, I cannot put tee after the for loop is done, as I have certain commands within the loop that I do not want logged to file.
I have tried to find an answer on StackOverflow already but I couldn't find anything that helped in this specific case.
I think I have managed to resolve my question through the following StackOverflow Thread:
Piping command output to tee but also save exit code of command
The issue is that the
|| continuewas not receiving the return status of the first stage of my pipeline, but the status returned bytee, which naturally was 0. To get the desired behaviour, it was necessary to write the following before this step (in my case at the top of the script as this behaviour was needed throughout)set -o pipefailSetting this step enables that the return status of the pipeline is equal to the last most non-zero return status, which then causes my loop to skip as needed!