Cómo depurar los guiones Bash

Cómo depurar los guiones Bash

Hay técnicas de entornos de programación tradicionales que pueden ayudar.
Algunas herramientas básicas como usar un editor con resaltado de sintaxis también ayudarán.
Hay opciones integradas que Bash proporciona para facilitar la depuración y su trabajo de administración del sistema Linux cotidiano.

En este artículo aprenderá algunos métodos útiles de depuración de scripts bash:

  • Cómo usar técnicas tradiconales
  • Cómo usar la opción XTRACE
  • Cómo usar otras opciones de bash
  • Cómo usar trampa

La herramienta de depuración más efectiva todavía es un pensamiento cuidadoso, junto con declaraciones de impresión juiciosamente colocadas. - Brian Kernighan, "Unix para principiantes" (1979)

Requisitos y convenciones de software utilizados

Requisitos de software y convenciones de línea de comandos de Linux
Categoría Requisitos, convenciones o versión de software utilizada
Sistema Cualquier distribución de GNU/Linux
Software GNU Bash
Otro N / A
Convenciones # - requiere que los comandos de Linux dados se ejecuten con privilegios raíz directamente como un usuario raíz o mediante el uso de sudo dominio
ps - Requiere que los comandos de Linux dados se ejecuten como un usuario regular no privilegiado

Uso de técnicas tradicionales

El código de depuración puede ser complicado, incluso si los errores son simples y obvios. Los programadores han aprovechado tradicionalmente herramientas como los depuradores y la sintaxis destacando en los editores para ayudarlos. No es diferente cuando se escribe guiones de Bash. Simplemente tener resaltado de sintaxis le permitirá captar errores mientras escribe el código, ahorrándole la tarea que requiere mucho tiempo de rastrear errores más tarde.

Algunos lenguajes de programación vienen con entornos de depuración complementarios, como GCC y GDB que le permiten atravesar el código, establecer puntos de interrupción, examinar el estado de todo en esos puntos de la ejecución y más, pero generalmente hay menos necesidad de un enfoque de mano dura como ese con scripts de shell ya que el código simplemente se interpreta en lugar de ser compilado en binarios.

Hay técnicas utilizadas en entornos de programación tradicionales que pueden ser útiles con scripts de bash complejos, como el uso de afirmaciones. Estas son básicamente una forma de afirmar explícitamente las condiciones o el estado de las cosas en un momento. Las afirmaciones pueden identificar incluso la más sutil de errores. Se pueden implementar como una función corta que muestra el tiempo, el número de línea y tal, o algo así:

$ echo "function_name (): el valor de \\ $ var es $ var"

Cómo usar la opción Bash Xtrace

Al escribir scripts de shell, la lógica de programación tiende a ser más corta y a menudo se contiene dentro de un solo archivo. Por lo tanto, hay algunas opciones de depuración incorporadas que podemos usar para ver qué va mal. La primera opción que menciona es probablemente la más útil: la xtrace opción. Esto se puede aplicar a un script invocando a Bash con el -X cambiar.

$ bash -x 


Esto le dice a Bash que nos muestre cómo se ve cada declaración después de la evaluación, justo antes de que se ejecute. Veremos un ejemplo de esto en acción en breve, pero primero contrasemos -X con su opuesto -V, que muestra cada línea antes de que se evalúe en lugar de después. Las opciones se pueden combinar y mediante el uso de ambos -X y -V Puede ver cómo se ven las declaraciones antes y después de las sustituciones variables.

Configuración X y V Opciones en la línea de comandos

Observe cómo usar -X y -V Opciones juntas nos permite ver la instrucción IF original antes del $ Usuario La variable se expande, gracias a la -V opción. También vemos en la línea comenzando con un signo más de cómo se ve la declaración nuevamente después de la sustitución, que nos muestra los valores reales comparados dentro del si declaración. En ejemplos más complicados, esto puede ser bastante útil.

Cómo usar otras opciones de bash

Las opciones de bash para la depuración se apagan de forma predeterminada, pero una vez que están activadas usando el comando establecer, permanecen encendidos hasta que se apague explícitamente. Si no está seguro de qué opciones están habilitados, puede examinar el ps- variable para ver el estado actual de todas las variables.

$ echo $- himbhs $ set -xv && echo $- himvxbhs 

Hay otro interruptor útil que podemos usar para ayudarnos a encontrar variables referenciadas sin tener ningún valor establecido. Este es el -u cambiar, y como -X y -V También se puede usar en la línea de comando, como vemos en el siguiente ejemplo:

Configuración u Opción en la línea de comando

Asignamos por error un valor de 7 a la variable llamada "nivel" y luego intentamos hacer eco de una variable llamada "puntaje" que simplemente resultó en imprimir nada en la pantalla. Absolutamente no se proporcionó información de depuración. Estableciendo nuestro -u Switch nos permite ver un mensaje de error específico, "Puntuación: variable no unida" que indica exactamente lo que salió mal.

Podemos usar esas opciones en scripts bash breves para darnos información de depuración para identificar problemas que de otro modo no activan los comentarios del intérprete bash. Caminemos por un par de ejemplos.

#!/bin/bash read -p "ruta a agregar:" $ ruta if ["$ ruta" = "/home/mike/bin"]; Entonces Echo $ ruta >> $ ruta echo "nueva ruta: $ ruta" else echo "no modificó la ruta" FI 
Copiar Usando X Opción Al ejecutar su script bash

En el ejemplo anterior, ejecutamos el script addPath normalmente y simplemente no modifica nuestro CAMINO. No nos da ninguna indicación de por qué o pistas de los errores cometidos. Ejecutándolo nuevamente usando el -X La opción nos muestra claramente que el lado izquierdo de nuestra comparación es una cadena vacía. $ es una cadena vacía porque accidentalmente ponemos un signo de dólar frente a "ruta" en nuestra declaración de lectura. A veces miramos bien un error como este y no parece mal hasta que obtenemos una pista y pensamos: "¿Por qué es $ evaluado en una cadena vacía?"

Mirando el siguiente ejemplo, tampoco obtenemos una indicación de un error del intérprete. Solo obtenemos un valor impreso por línea en lugar de dos. Este no es un error que detenga la ejecución del script, por lo que nos preguntan simplemente sin que se les dé ninguna pista. Utilizando el -u cambiar, inmediatamente recibimos una notificación de que nuestra variable j no está vinculado a un valor. Por lo tanto, estos son ahorradores en tiempo real cuando cometemos errores que no resultan en errores reales desde el punto de vista del intérprete bash.

#!/bin/bash para i en 1 2 3 do echo $ i $ j hecho 
Copiar Usando u Opción Ejecutando su script desde la línea de comando

Ahora seguramente estás pensando que eso suena bien, pero rara vez necesitamos ayuda para la depuración de errores cometidos en una línea en la línea de comandos o en scripts cortos como estos. Por lo general, luchamos con la depuración cuando lidiamos con scripts más y más complicados, y rara vez necesitamos establecer estas opciones y dejarlas establecidas mientras ejecutamos múltiples scripts. Configuración -xv opciones y luego ejecutar un script más complejo a menudo agregará confusión duplicando o triplicando la cantidad de salida generada.

Afortunadamente podemos usar estas opciones de una manera más precisa colocándolas dentro de nuestros scripts. En lugar de invocar explícitamente un shell bash con una opción desde la línea de comando, podemos establecer una opción agregándola a la línea shebang en su lugar.

#!/bin/bash -x

Esto establecerá el -X Opción para todo el archivo o hasta que no esté establecido durante la ejecución del script, lo que le permite simplemente ejecutar el script escribiendo el nombre de archivo en lugar de pasarlo a Bash como parámetro. Sin embargo, un script largo o uno que tenga mucha salida se volverá difícil de manejar utilizando esta técnica, así que veamos una forma más específica de usar opciones.



Para un enfoque más específico, envíe solo los bloques de código sospechosos con las opciones que desea. Este enfoque es excelente para los scripts que generan menús o salida detallada, y se logra mediante el uso de la palabra clave establecida con más o menos una vez más.

#!/bin/bash read -p "Se agregará la ruta:" $ Path Set -xv if ["$ Path" = "/Home/Mike/bin"]; Entonces echo de echo $ ruta >> $ ruta echo "nueva ruta: $ ruta" else echo "no modificó la ruta" FI set +xv 
Copiar Opciones de envoltura alrededor de un bloque de código en su script

Rodeamos solo los bloques de código que sospechamos para reducir la salida, lo que facilita la tarea en el proceso. Observe que encendemos nuestras opciones solo para el bloque de código que contiene nuestra declaración if-then-else, luego apague las opciones al final del bloque sospechoso. Podemos activar y apagar estas opciones varias veces en un solo script si no podemos reducir las áreas sospechosas, o si queremos evaluar el estado de las variables en varios puntos a medida que avanzamos a través del script. No hay necesidad de desactivar una opción si queremos que continúe por el resto de la ejecución del script.

Por la integridad, debemos mencionar también que hay depugadores escritos por terceros que nos permitirán atravesar el código de ejecución por línea. Es posible que desee investigar estas herramientas, pero la mayoría de las personas descubren que en realidad no son necesarias.

Como sugerirán los programadores experimentados, si su código es demasiado complejo para aislar bloques sospechosos con estas opciones, entonces el verdadero problema es que el código debe refactorizarse. El código demasiado complejo significa que los errores pueden ser difíciles de detectar y el mantenimiento puede llevar mucho tiempo y costoso.

Una última cosa a mencionar con respecto a las opciones de depuración de bash es que también existe una opción de globo de archivo y está configurada con -F. Configurar esta opción desactivará el globo (expansión de comodines para generar nombres de archivo) mientras está habilitado. Este -F La opción puede ser un interruptor utilizado en la línea de comando con Bash, después del shebang en un archivo o, como en este ejemplo, rodear un bloque de código.

#!/bin/bash echo "ignorar la opción deglobbing desactivada" ls * echo "Ignorar la opción de global de archivo" establecer -f ls * set +f 
Copiar Usando F opción para apagar el archivo de archivo

Cómo usar la trampa para ayudar a depurar

Hay técnicas más involucradas que vale la pena considerar si sus scripts son complicados, incluido el uso de una función de afirmación como se mencionó anteriormente. Uno de esos métodos a tener en cuenta es el uso de la trampa. Los scripts de shell nos permiten atrapar señales y hacer algo en ese punto.

Un ejemplo simple pero útil que puede usar en sus scripts bash es atrapar SALIDA.

#!/bin/bash trampa 'echo score es $ score, el estado es $ status' sale si [-z $ 1]; entonces status = "predeterminado" el más status = $ 1 fi scation = 0 if [$ user = 'Superman']; luego puntaje = 99 elif [$# -gt 1]; luego puntaje = $ 2 fi 
Copiar Usando trampa SALIDA para ayudar a depurar su guión

Como puede ver, simplemente descargar los valores actuales de las variables en la pantalla puede ser útil para mostrar dónde está fallando su lógica. El SALIDA La señal obviamente no necesita una explícita salida declaración a generar; En este caso el eco La declaración se ejecuta cuando se alcanza el final del script.

Otra trampa útil para usar con scripts bash es DEPURAR. Esto sucede después de cada declaración, por lo que puede usarse como una forma de fuerza bruta para mostrar los valores de las variables en cada paso de la ejecución del script.

#!/bin/bash trampa 'echo "línea $ lineno: score es $ score"' Debug score = 0 if ["$ user" = "Mike"]; Luego, deje "puntaje += 1" fi let "puntaje += 1" if ["$ 1" = "7"]; luego puntaje = 7 FI Salida 0 
Copiar Usando trampa DEPURAR para ayudar a depurar su guión

Conclusión

Cuando nota que su script bash no se comporta como se esperaba y la razón no es clara para usted por cualquier razón, considere qué información sería útil para ayudarlo a identificar la causa y luego usar las herramientas más cómodas disponibles para ayudarlo a determinar el problema. La opción XTRACE -X es fácil de usar y probablemente la más útil de las opciones presentadas aquí, así que considere probarlo la próxima vez que se enfrente con un guión que no está haciendo lo que pensó que sería.

Tutoriales de Linux relacionados:

  • Cómo propagar una señal a los procesos infantiles de una fiesta ..
  • Mastering Bash Script Loops
  • Cómo realizar operaciones de administración con Ansible ..
  • Bucles anidados en guiones Bash
  • Cómo usar subshells Bash dentro de declaraciones
  • Una introducción a la automatización, herramientas y técnicas de Linux
  • Cosas para instalar en Ubuntu 20.04
  • Cómo usar ADB Android Debug Bridge para administrar su Android ..
  • BASH IF Declaraciones: si, elif, de lo contrario, entonces, FI
  • Optimización de rendimiento de Linux: herramientas y técnicas