Analizando el modo estricto de bash
4 de enero de 2023
El famoso modo estricto de bash puede ayudarte a escribir scripts o guiones más seguros. Aunque en guiones más grandes tendrás que escribir código para manejar errores de manera correcta, el modo estricto puede ayudarte a detectar errores simples en guiones pequeños.
#!/bin/bash
set -euo pipefail
Vamos a explorar qué significan estas opciones. Verificado con GNU bash, versión 5.1.16.
Opción errexit
La opción set -e
detiene la ejecución de tu guión si algún comando regresa un
código de salida distinto a 0
.
Sin esta opción se ejecutaría el echo
.
#!/bin/bash
set -e
ls /no/existe
echo "¡¡¡no debería llegar aquí!!!"
$ ./guión.sh
ls: no se puede acceder a '/no/existe': No existe el fichero o el directorio
Si por alguna razón quieres ignorar el error de un comando, lo puedes ignorar
con || true
.
#!/bin/bash
set -e
ls /no/importa/que/no/existe || true
echo "ahora sí llega aquí"
$ ./guión.sh
ls: no se puede acceder a '/no/importa/que/no/existe': No existe el fichero o el directorio
ahora sí llega aquí
Para que set -e
detecte errores al asignar variables, se recomienda declarar
variables así.
a="$(cmd)"
b="$(cmd)"
export b
local c
c="$(cmd)"
d="$(cmd)"
readonly d
Opción nounset
La opción set -u
detiene la ejecución de tu guión si alguna variable se usa
sin primero antes declararla.
Sin esta opción se ejecutarían los dos comandos de echo
. La variable ${num}
estaría vacía.
#!/bin/bash
set -u
echo "mi número favorito es ${num}"
echo "¡¡¡no debería llegar aquí!!!"
$ ./guión.sh
./guión.sh: línea 4: num: variable sin asignar
Todo bien, pero existe una sorpresa si quieres usar esta opción y pasar argumentos a tu guión.
Si no pasas un argumento y intentas usar $1
, entonces set -u
detendrá la
ejecución. Para evitar esto, tienes que asignar $1
a una variable con un
valor por defecto.
#!/bin/bash
set -u
# Asignar $1 a num. Si $1 no existe, entonces asignar "" a num.
num=${1:-}
if [[ -z "${num}" ]]; then
echo "uso: $0 <número>"
exit 1
fi
echo "mi número favorito es ${num}"
$ ./guión.sh
uso: ./guión.sh <número>
$ ./guión.sh 42
mi número favorito es 42
Opción pipefail
La opción set -o pipefail
hace que la tuberías regresen el código de salida
del primer comando que falle.
Sin esta opción el código de salida sería 0
.
#!/bin/bash
set -o pipefail
ls /no/existe | sort
echo "código de salida: $?"
$ ./guión.sh
ls: no se puede acceder a '/no/existe': No existe el fichero o el directorio
código de salida: 2