To be on safe side, I'd like bash abort the execution of a script if it encounters a syntax error.
To my surprise, I can't achieve this. (set -e
is not enough.) Example:
#!/bin/bash
# Do exit on any error:
set -e
readonly a=(1 2)
# A syntax error is here:
if (( "${a[#]}" == 2 )); then
echo ok
else
echo not ok
fi
echo status $?
echo 'Bad: has not aborted execution on syntax error!'
Result (bash-3.2.39 or bash-3.2.51):
$ ./sh-on-syntax-err
./sh-on-syntax-err: line 10: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$
Well, we can't check $?
after every statement to catch syntax errors.
(I expected such safe behavior from a sensible programming language… perhaps this must be reported as a bug/wish to bash developers)
More experiments
if
makes no difference.
Removing if
:
#!/bin/bash
set -e # exit on any error
readonly a=(1 2)
# A syntax error is here:
(( "${a[#]}" == 2 ))
echo status $?
echo 'Bad: has not aborted execution on syntax error!'
Result:
$ ./sh-on-syntax-err
./sh-on-syntax-err: line 6: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$
Perhaps, it's related to exercise 2 from http://mywiki.wooledge.org/BashFAQ/105 and has something to do with (( ))
. But I find it still unreasonable to continue executing afte a syntax error.
No, (( ))
makes no difference!
It behaves bad even without the arithmetic test! Just a simple, basic script:
#!/bin/bash
set -e # exit on any error
readonly a=(1 2)
# A syntax error is here:
echo "${a[#]}"
echo status $?
echo 'Bad: has not aborted execution on syntax error!'
Result:
$ ./sh-on-syntax-err
./sh-on-syntax-err: line 6: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$
Best Answer
Wrapping the whole into a function seems to do the trick:
Result:
Though I have no clue why - maybe someone else can explain?