Abans de res, comentar que l’eina shellcheck ens ajuda a revisar els script i detecta alguns dels errors comentats aquí, per tant, abans d’executar un script, el podem comprovar amb:
shellcheck nom_script
Dit això, anem al tema…
Quan una comanda externa falla, l’script es segueix executant i (normalment) això no és el què volem.
Es pot comprovar el codi de sortida de cada comanda, però això es complica si utilitzem pipes
Per això existeix set i pipefile
Per exemple, si tenim un script amb aquestes tres línies…
echo "hola" ls prova echo "adéu"
veurem el següent…
hola ls: cannot access 'prova': No such file or directory adéu
S’han executat les tres línies tot i haver hagut un error.
Si afegim set -e al començament de l’script, l’script s’aturarà al error de la línia 2, fent que no executi la línia 3 …
hola ls: cannot access 'prova': No such file or directory
I si mirem el codi de retorn, veurem que no és zero …
echo $? 2
El pipes ens compliquem més la detecció d’aquests errors perquè el codi de retorn es perd enmig de la seqüència.
Per exemple…
false | true echo $? 0
No hem detectat el codi de retorn 1 del primer false.
Bash té una variable (array) que captura els codis de retorn de cada programa d’una seqüencia: PIPESTATUS
false | true | false | true echo "${PIPESTATUS[0]} ${PIPESTATUS[1]} ${PIPESTATUS[2]} ${PIPESTATUS[3]}" 1 0 1 0
Pot ser útil per saber quina comanda de la seqüència ha fallat, però aquesta informació es perd molt ràpid (a l’execució de la següent comanda) i no evita que l’script es segueixi executant.
Per això és interessant combinar set -e i pipefile, així…
set -eo pipefail
ara, al primer error que trobi, aturarà l’script.
Important, -o pipefail ha d’anar sempre al final!
També, tenim l’opció d’aturar l’script en cas que alguna variable no tingui cap valor assignat: set -u
set -eou pipefail echo "hola" echo "$notset" echo "adéu"
Finalment, tenim la opció set -x. El què fa és mostrar per pantalla el què va fent l’script.