Respuestas:
Un enfoque sería agregar set -e
al comienzo de su secuencia de comandos. Eso significa (de help set
):
-e Exit immediately if a command exits with a non-zero status.
Entonces, si alguno de sus comandos falla, el script se cerrará.
Alternativamente, puede agregar exit
declaraciones explícitas en los posibles puntos de falla:
command || exit 1
set -e
es la única forma en que sé hacer eso.
set -e
son sleep
(al break
ser una construcción especial, la secuencia de comandos se cerrará al fallar en la mayoría de los shells, los comandos dentro if
o a la izquierda &&
no se verán afectados set -e
, n=...
podrían fallar si n
es de solo lectura, pero luego eso también saldría del guión set -e
), por lo que la interpretación suena bastante improbable. Estoy de acuerdo en que la pregunta está mal redactada.
Puede salir de un script en cualquier lugar utilizando la palabra clave exit
. También puede especificar un código de salida con el fin de indicar a los demás programas que o cómo suspendido el guión, por ejemplo, exit 1
o exit 2
etc (Por convención, el código de salida 0 es para el éxito y el fracaso mayor cosa que no sea 0 significa, sin embargo, también por convención, salida los códigos superiores a 127 están reservados para la terminación anormal (por ejemplo, por una señal)).
La construcción genérica para salir en caso de falla es
if [ failure condition ]; then
exit n
fi
Con adecuado failure condition
y n
. Pero en escenarios específicos puede proceder de manera diferente. Ahora, para su caso, interpreto su pregunta de que si alguna de las cinco invocaciones de gksu
error falla, entonces quiere decir salir. Una forma es usar una función como esta
function try_command {
for i in 1 2 3 4 5 ; do
if gksu command ; then
return 0
fi
fi
exit 1
}
y luego invoque el bucle try_command
.
Hay (más) formas avanzadas o sofisticadas de cómo abordar su pregunta. Sin embargo, la solución anterior es más accesible para los principiantes que, por ejemplo, la solución de Stephane.
attempt=0
until gksu command; do
attempt=$((attempt + 1))
if [ "$attempt" -gt 5 ]; then
exit 1
fi
done
exit
sale del script a menos que se llame en una subshell. Si esa parte de la secuencia de comandos se encuentra en un subnivel, por ejemplo, porque está dentro (...)
o $(...)
o parte de una línea de tubería, entonces sólo saldrá de que subnivel .
En ese caso, si desea que el script salga además de la subshell, deberá llamar exit
a esa subshell para que salga.
Por ejemplo, aquí con 2 niveles anidados de subcapas:
(
life=hard
output=$(
echo blah
[ "$life" = easy ] || exit 1 # exit subshell
echo blih not run
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
echo not run either
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
Puede volverse más complicado si la subshell es parte de una tubería. bash
tiene una $PIPESTATUS
matriz especial , similar a zsh
la $pipestatus
que puede ayudarte aquí:
{
echo foo
exit 1
echo bar
} | wc -c
subshell_ret=${PIPESTATUS[0]}
if [ "$subshell_ret" -ne 0 ]; then
exit "$subshell_ret"
fi
Trap realizará una acción al recibir una señal.
trap "echo EXIT; exit" 0
trap "echo HUP; exit" 1
trap "echo CTL-C; exit" 2
trap "echo QUIT; exit" 3
trap "echo ERR; exit" ERR
n=0
until [ $n -ge 5 ]
do
n=$[$n+1]
echo $n
sleep 3
done
Ejecuta esto y deja que salga normalmente. Atrapa la señal 0.
EXIT
Ejecútelo de nuevo e interrumpa con ^ C. Atrapa tanto la señal 2 como la señal 0.
CTL-C
EXIT
Un estado de salida distinto de cero quedará atrapado en ERR
ERR
EXIT
set -e
. Sin embargo, realmente no se aplica aquí. El OP quiere salir del script después de 5 intentos fallidos de ejecutar el comando.