Salir del script de Shell basado en el código de salida del proceso [duplicado]

Resuelto Mark Roddy asked hace 16 años • 9 respuestas

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?

Mark Roddy avatar Sep 18 '08 13:09 Mark Roddy
Aceptado

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 sedparte de la canalización realmente funciona y devuelve 0).

En realidad, el bashshell 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 falsecomando, 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 PIPESTATUSelementos por turno, almacenándolo en rcsi fuera mayor que el rcvalor anterior.

paxdiablo avatar Sep 18 '2008 06:09 paxdiablo

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 setarchivo incorporado.

Jeff Hill avatar Sep 18 '2008 06:09 Jeff Hill