Tengo un script de shell que ejecuta una serie de comandos. ¿Cómo puedo hacer que el script de shell salga si alguno de los comandos sale con un código de salida distinto de cero?Salir del script de shell basado en el código de salida del proceso
Respuesta
Después de cada comando, el código de salida puede ser encontrado en la variable $?
por lo que tendría algo como:
ls -al file.ext
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
Necesita ser cuidadoso de comandos por tubería desde la $?
sólo le da el código de retorno del último elemento de la tubería así, en el código:
ls -al file.ext | sed 's/^/xx: /"
no devolverá un código de error si el archivo doesn' t existe (ya que la parte sed
de la tubería realmente funciona, devolviendo 0).
El shell bash
realmente proporciona una matriz que puede ayudar en ese caso, que es PIPESTATUS
. Esta matriz tiene un elemento para cada uno de los componentes de canalización, que se puede acceder de forma individual como ${PIPESTATUS[0]}
:
pax> false | true ; echo ${PIPESTATUS[0]}
1
Tenga en cuenta que esto es conseguir que el resultado del comando false
, no toda la tubería. También puede obtener toda la lista para procesar como mejor le parezca:
pax> false | true | false; echo ${PIPESTATUS[*]}
1 0 1
Si quisiera obtener el código de error más grande de una tubería, podría utilizar algo como:
true | true | false | true | false
rcs=${PIPESTATUS[*]}; rc=0; for i in ${rcs}; do rc=$(($i > $rc ? $i : $rc)); done
echo $rc
Esto pasa por cada uno de los elementos PIPESTATUS
a su vez, almacenándolo en rc
si fue mayor que el valor anterior rc
.
La misma característica en una sola línea de código portátil: 'ls -al file.ext || exit $? '([[]] no es portable) – MarcH
MarcH, creo que encontrará que' [[]] 'es bastante portable en' bash', que es lo que la pregunta está etiquetada :-) Curiosamente, 'ls' no funciona en' command.com', por lo que tampoco es portátil, aunque lo sé, es el mismo tipo de argumento que presentas. – paxdiablo
Sé que esto es antiguo, pero debe tenerse en cuenta que puede obtener el código de salida de comandos en una tubería a través de la matriz 'PIPESTATUS' (es decir,' $ {PIPESTATUS [0]} 'para el primer comando,' $ { PIPESTATUS [1]} 'para el segundo, o' $ {PIPESTATUS [*]} 'para obtener una lista de todas las estaciones de salida. – DevSolar
En bash esto es fácil, simplemente atarlas con & &:
command1 && command2 && command3
También puede utilizar el anidado construcción if:
if command1
then
if command2
then
do_something
else
exit
fi
else
exit
fi
"set -e
" es probablemente la forma más fácil de hacerlo. Solo ponlo antes de cualquier comando en tu programa.
¿Qué hace? Cualquier enlace a documentos por favor? –
@SwaroopCH 'set -e' su script se cancelará si algún comando en su script sale con estado de error y no ha manejado este error. – Andrew
Si quieres trabajar con $ ?, deberás comprobarlo después de cada comando, ya que $? se actualiza después de que sale cada comando. Esto significa que si ejecuta una tubería, solo obtendrá el código de salida del último proceso en la tubería.
Otro enfoque es hacer esto:
set -e
set -o pipefail
Si pones esto en la parte superior de la secuencia de comandos shell, se ve como fiesta se hará cargo de esto para usted. Como se señaló en un póster anterior, "set -e" hará que bash salga con un error en cualquier comando simple. "set -o pipefail" hará que bash salga con un error en cualquier comando en una tubería también.
Consulte here o here para obtener un poco más de discusión sobre este problema. Here es la sección manual de bash en el conjunto incorporado.
Esto realmente debería ser la respuesta principal: es mucho, mucho más fácil hacer esto que usar 'PIPESTATUS' y verificar los códigos de salida en todas partes. – candu
'#!/Bin/bash -e' es la única forma de iniciar un script de shell. Siempre puedes usar cosas como 'foo || handle_error $? 'si necesita examinar los estados de salida. –
Si solo llama a exit en el bash sin parámetros, devolverá el código de salida del último comando. Combinado con O, bash solo debería invocar exit, si el comando anterior falla. Pero no he probado esto.
command1 || exit; command2 || exit;
The Bash también almacenará el código de salida del último comando en la variable $ ?.
de fiesta:
# this will trap any errors or commands with non-zero exit status
# by calling function catch_errors()
trap catch_errors ERR;
#
# ... the rest of the script goes here
#
function catch_errors() {
# do whatever on errors
#
#
echo "script aborted, because of errors";
exit 0;
}
Probablemente no debería "salir 0", ya que eso indica éxito. – nobar
exit_code = $ ?; echo "script abortado, debido a errores"; exit $ exit_code – RaSergiy
@ HAL9001 ¿Tiene evidencia de esto? Documentación de IBM [dice lo contrario] (http://www.ibm.com/developerworks/aix/library/au-usingtraps/#list4). –
http://cfaj.freeshell.org/shell/cus-faq-2.html#11
¿Cómo consigo el código de salida de
cmd1
encmd1|cmd2
En primer lugar, tenga en cuenta que
cmd1
salida el código podría ser distinto de cero y todavía no significa significa un error. Esto sucede por ejemplo encmd | head -1
es posible observar un código de salida de 141 (o 269 con ksh93) de
cmd1
, pero es porquecmd
fue interrumpida por una señal SIGPIPE cuandohead -1
terminado después de haber leído una sola línea.Conocer el estado de salida de los elementos de una tubería
cmd1 | cmd2 | cmd3
a. con zsh:
Los códigos de salida se proporcionan en la matriz especial de pipestatus. código
cmd1
salida está en$pipestatus[1]
,cmd3
código de salida en$pipestatus[3]
, de manera que$?
es siempre el mismo que$pipestatus[-1]
.b. con bash:
Los códigos de salida se proporcionan en la matriz especial
PIPESTATUS
. códigocmd1
salida está en${PIPESTATUS[0]}
,cmd3
código de salida en${PIPESTATUS[2]}
, de manera que$?
es siempre el mismo que${PIPESTATUS: -1}
....
Para más detalles ver la siguiente link.
[ $? -eq 0 ] || exit $?; # exit for none-zero return code
¿No debería ser '' exit $? '' (No parens)? – malthe
#
#------------------------------------------------------------------------------
# run a command on failure exit with message
# doPrintHelp: doRunCmdOrExit "$cmd"
# call by:
# set -e ; doRunCmdOrExit "$cmd" ; set +e
#------------------------------------------------------------------------------
doRunCmdOrExit(){
cmd="[email protected]" ;
doLog "DEBUG running cmd or exit: \"$cmd\""
msg=$($cmd 2>&1)
export exit_code=$?
# if occured during the execution exit with error
error_msg="Failed to run the command:
\"$cmd\" with the output:
\"$msg\" !!!"
if [ $exit_code -ne 0 ] ; then
doLog "ERROR $msg"
doLog "FATAL $msg"
doExit "$exit_code" "$error_msg"
else
#if no errors occured just log the message
doLog "DEBUG : cmdoutput : \"$msg\""
doLog "INFO $msg"
fi
}
#eof func doRunCmdOrExit
Raramente hay una razón para usar '$ *'; use '" $ @ "' en su lugar para conservar espacios y comodines. –
- 1. Redireccionando la salida del comando ps, obteniendo el ID del proceso y matando ese proceso usando el script de shell
- 2. shell - obtener el código de salida del proceso en segundo plano
- 3. Captura del código de salida del proceso sudo-run
- 4. Salida automática del script bash shell en el error
- 5. Cómo salir del shell de emacs
- 6. Análisis del argumento del script de Shell
- 7. Proceso de eliminación en Shell Script
- 8. Salir del proceso secundario después de os.fork()
- 9. Error extraño de SSIS (Código de salida del proceso 255)
- 10. shell script salida al portapapeles
- 11. ¿Cómo obtener el ID del proceso del nombre del proceso?
- 12. Salida del último comando de shell
- 13. Lectura del script de shell Resultado en C# .Net Program
- 14. ejecutando el comando de shell en el fondo del script
- 15. ¿El lote se libera automáticamente al salir del proceso?
- 16. Obteniendo el código de estado de salida del comando 'ftp' en el shell de linux
- 17. ¿Directorio actual del script de Shell?
- 18. Analizando los argumentos del script de shell
- 19. Código de salida del proceso cuando se mata el proceso forzosamente
- 20. ¿Cómo imprimir el resultado del script de shell en CMake?
- 21. Obtener salida en vivo del proceso
- 22. enviar salida al archivo desde el script de shell
- 23. Salida JSON del script Bash
- 24. Shell script generando un proceso después de un retraso
- 25. Cómo devolver el código de salida del proceso generado en la secuencia de comandos Esperar?
- 26. ¿Cómo obtener el segundo último argumento del script de shell?
- 27. Detección del tipo de flujo de salida de un script de shell
- 28. ¿Cómo redirecciono el resultado de un script de shell completo dentro del script?
- 29. ¿Puede gcc salir el código C después del preprocesamiento?
- 30. Salida de canal del comando de shell a un script de python
me respondió asumiendo que usted está utilizando bash, pero si es una cáscara muy diferente que puede especificar en su puesto? –