Salir del script de Shell basado en el código de salida del proceso [duplicado]
Tengo un script de shell que ejecuta varios comandos. ¿Cómo hago para que el script de shell salga si alguno de los comandos sale con un código de salida distinto de cero?
Después de cada comando, el código de salida se puede encontrar en la $?
variable, por lo que tendría algo como:
ls -al file.ext
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
Debe tener cuidado con los comandos canalizados, ya que $?
solo le proporciona el código de retorno del último elemento en el canal, por lo que, en el código:
ls -al file.ext | sed 's/^/xx: /"
no devolverá un código de error si el archivo no existe (ya que la sed
parte de la canalización realmente funciona y devuelve 0).
En realidad, el bash
shell proporciona una matriz que puede ayudar en ese caso, siendo PIPESTATUS
. Esta matriz tiene un elemento para cada uno de los componentes de la canalización, al que puede acceder individualmente como ${PIPESTATUS[0]}
:
pax> false | true ; echo ${PIPESTATUS[0]}
1
Tenga en cuenta que esto le proporciona el resultado del false
comando, no toda la canalización. También puede obtener la lista completa para procesarla como mejor le parezca:
pax> false | true | false; echo ${PIPESTATUS[*]}
1 0 1
Si desea obtener el código de error más grande de una canalización, puede usar algo como:
true | true | false | true | false
rcs=${PIPESTATUS[*]}; rc=0; for i in ${rcs}; do rc=$(($i > $rc ? $i : $rc)); done
echo $rc
Este recorre cada uno de los PIPESTATUS
elementos por turno, almacenándolo en rc
si fuera mayor que el rc
valor anterior.
Si desea trabajar con $?
, deberá verificarlo después de cada comando, ya que $?
se actualiza después de que sale cada comando. Esto significa que si ejecuta una canalización, solo obtendrá el código de salida del último proceso de la canalización.
Otro enfoque es hacer esto:
set -e
set -o pipefail
Si coloca esto en la parte superior del script de shell, parece que Bash se encargará de esto por usted. Como señaló un usuario anterior, "set -e" hará que Bash salga con un error en cualquier comando simple. "set -o pipefail" también hará que Bash salga con un error en cualquier comando de una canalización.
Consulte aquí o aquí para conocer un poco más de discusión sobre este problema. Aquí está la sección del manual de Bash sobre el set
archivo incorporado.