I made a few changes to a bash script recently, and made a syntax error in a function. I know what the error is (spaces around the assignment: local max_loops = 4 instead of local max_loops=4).
However, I didn't spot this at first - it's a long script with a lot of output and it just output errors but continued running - the function returned true, so despite testing for success of the function I got no errors.
A simplified version is here (updated based on comments and answers below):
!/bin/bash
set -e
do_magic(){
set -e
local i=1
local max_loops
max_loops = 4 # This is the error i want the script/function to break on
while [ $i -le $max_loops ]; do
echo "Loop: $i"
i=$(( i + 1 ))
done
}
if do_magic; then
echo "Ran OK"
else
echo "Error running...."
fi
(My actual function does stuff in the loop and returns an error code if the stuff fails). This just outputs:
$ ./foo.sh
./foo.sh: line 1: !/bin/bash: No such file or directory
./foo.sh: line 8: max_loops: command not found
./foo.sh: line 9: [: 1: unary operator expected
Ran OK
My Question: Is there any generic way to say that functions with unhandled errors return a non-zero value? I tried set -e (I know I shouldn't need it twice, but tried both for safeties sake) and it doesn't seem to help.
I'd be happy either with the whole script breaking and stopping, or with the function breaking and returning a non-zero error. But i don't want to see "Ran OK" here...
I've fixed the actual error here, but I'd like to make the script more robust.
$[ ]is a non-POSIX-compliant extension for backward compatibility with ancient 1970s-era shells. Don't ever use it in new code --i=$(( i + 1 ))is the POSIX-standardized syntax.[isn't bash syntax, so it's not actually a shell syntax error. A failure with it is just the same as if some other random program you were calling were given incorrect command-line arguments, insofar as the shell is concerned. (Yes, it's implemented as a builtin, but they behave identically to external commands insofar as parsing, exit status, error handling, etc etc are concerned).do_magic() {with nofunction-- see wiki.bash-hackers.org/scripting/obsolete;function funcname() {is an amalgam between POSIX sh and ksh function declaration syntax, while being compatible with neither).local max_loops = 4, even ifset -eis in place?"localline as its minimal reproducible example.