Opcions per contorlar errors a scripts bash

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.

2022-03-23T10:48:27+01:0023 03 2022|bash|