Dla pewności chciałbym bash przerwać wykonywanie skryptu, jeśli napotka błąd składniowy.
Ku mojemu zaskoczeniu nie mogę tego osiągnąć. ( set -e
to za mało.) Przykład:
#!/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!'
Wynik (bash-3.2.39 lub 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!
$
Nie możemy sprawdzać $?
po każdej instrukcji, aby wyłapać błędy składniowe.
(Spodziewałem się takiego bezpiecznego zachowania z rozsądnego języka programowania ... być może należy to zgłosić jako błąd / chęć bashowania deweloperów)
Więcej eksperymentów
if
nie robi różnicy.
Usuwanie 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!'
Wynik:
$ ./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!
$
Być może jest to związane z ćwiczeniem 2 z http://mywiki.wooledge.org/BashFAQ/105 i ma coś wspólnego z tym (( ))
. Ale nadal uważam, że nadal nieuzasadnione jest kontynuowanie wykonywania po błędzie składni.
Nie, (( ))
nie ma znaczenia!
Zachowuje się źle nawet bez testu arytmetycznego! Po prostu prosty, podstawowy skrypt:
#!/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!'
Wynik:
$ ./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!
$
set -e
nie zadziałało. Ale moje pytanie wciąż ma sens. Czy można przerwać dowolny błąd składniowy?
set -e
nie wystarczy, ponieważ błąd składniowy znajduje się wif
instrukcji. Gdziekolwiek indziej powinien przerwać skrypt.