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 -eto 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 -enie zadziałało. Ale moje pytanie wciąż ma sens. Czy można przerwać dowolny błąd składniowy?
set -enie wystarczy, ponieważ błąd składniowy znajduje się wifinstrukcji. Gdziekolwiek indziej powinien przerwać skrypt.