GNU/Linux >> Tutoriales Linux >  >> Linux

Códigos de salida de la línea de comandos de Bash desmitificados

Cuando ejecuta un comando o ejecuta un script, recibe un código de salida . Un código de salida es una respuesta del sistema que informa un éxito, un error u otra condición que brinda una pista sobre qué causó un resultado inesperado de su comando o secuencia de comandos. Sin embargo, es posible que nunca sepa sobre el código, porque un código de salida no se revela a menos que alguien se lo pida. Los programadores usan códigos de salida para ayudar a depurar su código.

Nota: A menudo verá código de salida denominado estado de salida o incluso como códigos de estado de salida . Los términos se usan indistintamente excepto en la documentación. Espero que mi uso de los dos términos sea claro para usted.

No soy programador. Me cuesta admitirlo, pero es verdad. He estudiado BASIC, FORTRAN y algunos otros lenguajes tanto formal como informalmente, y tengo que decir que definitivamente no soy programador. Claro, puedo escribir y programar un poco en PHP, Perl, Bash e incluso PowerShell (sí, también soy administrador de Windows), pero nunca podría ganarme la vida programando porque soy demasiado lento para escribir código. y el ensayo y error no es una estrategia de depuración eficiente. Es triste, de verdad, pero soy lo suficientemente competente copiando y adaptando el código encontrado para poder realizar las tareas requeridas. Y, sin embargo, también uso códigos de salida para descubrir dónde están mis problemas y por qué las cosas van mal.

[ También te puede interesar: Un poco de magia para copiar archivos SSH en la línea de comandos. ]

Los códigos de salida son útiles hasta cierto punto, pero también pueden ser vagos. Por ejemplo, un código de salida de 1 es un cubo genérico para errores varios y no es útil en absoluto. En este artículo, explico el puñado de códigos de error reservados , cómo pueden ocurrir y cómo usarlos para descubrir cuál es su problema. Un código de error reservado es uno que utiliza Bash y no debe crear sus propios códigos de error que entren en conflicto con ellos.

Suficiente historia de fondo. Es hora de ver ejemplos de lo que genera códigos/estados de error.

Extracción del elusivo código de salida

Para mostrar el código de salida del último comando que ejecutó en la línea de comando, use el siguiente comando:

$ echo $?

La respuesta mostrada no contiene pompa ni circunstancia. Es simplemente un número. También puede recibir un mensaje de error de shell de Bash que describe el error con más detalle, pero el código de salida y el error de shell juntos deberían ayudarlo a descubrir qué salió mal.

Estado de salida 0

Un estado de salida de 0 es el mejor escenario posible, en términos generales. Le dice que su último comando o script se ejecutó con éxito. El éxito es relativo porque el código de salida solo le informa que el script o comando se ejecutó bien, pero el código de salida no le dice si la información que contiene tiene algún valor. Los ejemplos ilustrarán mejor lo que estoy describiendo.

Por ejemplo, enumere los archivos en su directorio de inicio. No tengo nada en mi directorio de inicio aparte de archivos y directorios ocultos, así que no hay nada que ver aquí, pero al código de salida no le importa nada más que el éxito de la ejecución del comando:

$ ls
$ echo $?
0

El código de salida de 0 significa que ls el comando se ejecutó sin problema. Aunque, de nuevo, la información del código de salida no me proporciona ningún valor real.

Ahora, ejecuta el ls comando en /etc directorio y luego mostrar el código de salida:

$ ls /etc
**Many files**
$ echo $?
0

Puede ver que cualquier ejecución exitosa da como resultado un código de salida de 0, incluido algo que es totalmente incorrecto, como emitir el cat comando en un archivo ejecutable binario como el ls comando: 

$ cat /usr/bin/ls
**A lot of screen gibberish and beeping**
$ echo $?
0

Estado de salida 1

Usando el ejemplo anterior, pero agregando la lista larga y las opciones recursivas (-lR ), recibe un nuevo código de salida de 1:

$ ls -lR /etc
**A lengthy list of files**
$ echo $?
1

Aunque el resultado del comando parece que todo salió bien, si se desplaza hacia arriba verá varios errores de "Permiso denegado" en la lista. Estos errores dan como resultado un estado de salida de 1, que se ​​describe como "operaciones no permitidas". Aunque podría esperar que un error de "Permiso denegado" lleve a un estado de salida de 1, estaría equivocado, como verá en la siguiente sección.

Sin embargo, dividir por cero le da un estado de salida de 1. También recibe un error del shell para informarle que la operación que está realizando es "no permisible":

$ let a=1
$ let b=0
$ let c=a/b
-bash: let: c=a/b: division by 0 (error token is "b")
$ echo $?
1

Sin un error de shell, un estado de salida de 1 no es muy útil, como puede ver en el primer ejemplo. En el segundo ejemplo, sabes por qué recibiste el error porque Bash te lo dice con un mensaje de error de shell. En general, cuando reciba un estado de salida de 1, busque las operaciones no permitidas (Permiso denegado mensajes) mezclados con sus éxitos (como enumerar todos los archivos en /etc , como en el primer ejemplo de esta sección).

Estado de salida 2

Como se indicó anteriormente, una advertencia de shell de "Permiso denegado" da como resultado un estado de salida de 2 en lugar de 1. Para comprobarlo, intente enumerar los archivos en /root :

$ ls /root
ls: cannot open directory '/root': Permission denied
$ echo $?
2

El estado de salida 2 aparece cuando hay un problema de permisos o falta una palabra clave en un comando o secuencia de comandos. Un ejemplo de palabra clave faltante es olvidar agregar un done en el do de un script círculo. El mejor método para la depuración de secuencias de comandos con este estado de salida es emitir su comando en un shell interactivo para ver los errores que recibe. Este método generalmente revela dónde está el problema.

Los problemas de permisos son un poco menos difíciles de descifrar y depurar que otros tipos de problemas. Lo único que significa "Permiso denegado" es que su comando o script está intentando violar una restricción de permiso.

Estado de salida 126

El estado de salida 126 es un código de error de permisos interesante. La forma más fácil de demostrar cuándo aparece este código es crear un archivo de secuencia de comandos y olvidarse de otorgar permiso de ejecución a ese archivo. Aquí está el resultado:

$ ./blah.sh
-bash: ./blah.sh: Permission denied
$ echo $?
126

Este problema de permisos no es de acceso, sino de configuración, como en modo. Para deshacerse de este error y recibir un estado de salida de 0, emita chmod +x blah.sh .

Nota: Recibirá un estado de salida de 0 incluso si el archivo ejecutable no tiene contenido. Como se indicó anteriormente, el "éxito" está abierto a interpretación.

Recibo un estado de salida de 126. Este código en realidad me dice qué está mal, a diferencia de los códigos más vagos.

Estado de salida 127

El estado de salida 127 le indica que ha ocurrido una de estas dos cosas:el comando no existe o no se encuentra en su ruta ($PATH ). Este código también aparece si intenta ejecutar un comando que se encuentra en su directorio de trabajo actual. Por ejemplo, la secuencia de comandos anterior a la que le dio permiso de ejecución está en su directorio actual, pero intenta ejecutar la secuencia de comandos sin especificar dónde está:

$ blah.sh
-bash: blah.sh: command not found
$ echo $?
127

Si este resultado ocurre en una secuencia de comandos, intente agregar la ruta explícita al ejecutable o secuencia de comandos del problema. La ortografía también cuenta al especificar un ejecutable o un script.

[ Los lectores también disfrutaron: 10 comandos básicos de Linux que debe conocer. ]

Estado de salida 128

El estado de salida 128 es la respuesta recibida cuando se usa un código de salida fuera de rango en la programación. Según mi experiencia, no es posible producir el estado de salida 128. Intenté varias acciones para un ejemplo, y no puedo hacer que suceda. Sin embargo, puedo producir un código adyacente de estado de salida 128. Si su código de salida excede 256, el estado de salida devuelto es su código de salida restado por 256. Este resultado suena extraño y en realidad puede crear un estado de salida incorrecto. Consulte los ejemplos para comprobarlo usted mismo.

Usando un código de salida de 261, cree un estado de salida de 5:

$ bash
$ exit 261
exit
$ echo $?
5

Para producir un estado de salida errante de 0:

$ bash
$ exit 256
exit
$ echo $?
0

Si usa 257 como código de salida, su estado de salida es 1, y así sucesivamente. Si el código de salida es un número negativo, el estado de salida resultante es ese número restado de 256. Entonces, si su código de salida es 20, entonces el estado de salida es 236.

Preocupante, ¿no? La solución, para mí, es evitar el uso de códigos de salida que están reservados y fuera de rango. El rango adecuado es 0-255.

Estado de salida 130

Si está ejecutando un programa o secuencia de comandos y presiona Ctrl-C para detenerlo, su estado de salida es 130. Este estado es fácil de demostrar. Emitir ls -lR / y luego presione inmediatamente Ctrl-C:

$ ls -lR /
**Lots of files scrolling by**
^C
$ echo $?
130

No hay mucho más que decir sobre este. No es un estado de salida muy útil, pero aquí está para su referencia.

Estado de salida 255

Este estado final de salida reservada es fácil de producir pero difícil de interpretar. La documentación que encontré indica que recibe el estado de salida 255 si usa un código de salida que está fuera del rango 0-255.

Descubrí que este estado también se puede producir de otras maneras. He aquí un ejemplo:

$ ip
**Usage info for the ip command**
  
$ echo $?
255

Algunas autoridades independientes dicen que 255 es un código de error de falla general. No puedo ni confirmar ni negar esa afirmación. Solo sé que puedo producir el estado de salida 255 ejecutando comandos particulares sin opciones.

[ Artículo relacionado: 10 comandos Linux esenciales más que debes conocer. ]

Conclusión

Ahí lo tiene:una descripción general de los números de estado de salida reservados, sus significados y cómo generarlos. Mi consejo personal es verificar siempre los permisos y las rutas de todo lo que ejecute, especialmente en un script, en lugar de confiar en los códigos de estado de salida. Mi método de depuración es que cuando un comando no funciona correctamente en un script, ejecuto el comando individualmente en un shell interactivo. Este método funciona mucho mejor que probar tácticas sofisticadas con descansos y salidas. Sigo este camino porque (la mayoría de las veces) mis errores están relacionados con los permisos, por lo que he recibido capacitación para comenzar allí.

Diviértete revisando tus estados, y ahora es el momento de que me vaya.

[ ¿Quiere probar Red Hat Enterprise Linux? Descárgalo ahora gratis. ]


Linux
  1. ¿Diferencia entre 'y' en la línea de comando (bash)?

  2. ¿Cómo buscar códigos de salida para aplicaciones?

  3. ¿Pasar argumentos de línea de comando a Bash Script?

  4. ¿Cómo evaluará Bash el siguiente código?

  5. 5 Finalización estándar disponible en la línea de comandos de Linux Bash

Comando de espera bash

Comando de salida de Bash y códigos de salida

Comando Bash printf

Cómo mostrar el historial de Bash sin números de línea

Argumentos de la línea de comando para ejecutar la ventana acoplable

¿Qué hace la -e en un bash shebang?