script depurar debugger debuggear debug como bash shell

bash - debugger - depurar un script linux



¿Cómo depurar un script bash? (12)

set + x = @ECHO OFF, configure -x = @ECHO ON.

Puede agregar la opción -xv al Shebang estándar de la siguiente manera:

#!/bin/bash -xv

-x : Muestra los comandos y sus argumentos a medida que se ejecutan.
-v : Muestra líneas de entrada de shell a medida que se leen.

ltrace es otra utilidad de Linux similar a strace . Sin embargo, ltrace enumera todas las llamadas de biblioteca que se ltrace en un ejecutable o en un proceso en ejecución. Su nombre en sí proviene del rastreo de llamadas a bibliotecas. Por ejemplo:

ltrace ./executable <parameters> ltrace -p <PID>

Source

¿Hay alguna forma de depurar un script bash? Por ejemplo, algo que imprime una especie de registro de ejecución como "línea de llamada 1", "línea de llamada 2", etc.


Algún truco para depurar scripts bash :

Usando set -[nvx]

Además de

set -x

y

set +x

para detener el vaciado.

Me gustaría hablar sobre el set -v qué volcado es tan pequeño como el menos desarrollado.

bash <<<$''set -x/nfor i in {0..9};do/n/techo $i/n/tdone/nset +x'' 2>&1 >/dev/null|wc -l 21 for arg in x v n nx nv nvx;do echo "- opts: $arg" bash 2> >(wc -l|sed s/^/stderr:/) > >(wc -l|sed s/^/stdout:/) <<eof set -$arg for i in {0..9};do echo $i done set +$arg echo Done. eof sleep .02 done - opts: x stdout:11 stderr:21 - opts: v stdout:11 stderr:4 - opts: n stdout:0 stderr:0 - opts: nx stdout:0 stderr:0 - opts: nv stdout:0 stderr:5 - opts: nvx stdout:0 stderr:5

Variables de volcado o seguimiento sobre la marcha

Para probar algunas variables, uso alguna vez esto:

bash <(sed ''18ideclare >&2 -p var1 var2'' myscript.sh) args

para añadir:

declare >&2 -p var1 var2

en la línea 18 y ejecuta el script resultante (con args ), sin tener que editarlos.

por supuesto, esto podría usarse para agregar el set [+-][nvx] :

bash <(sed ''18s/$//ndeclare -p v1 v2 >/&2/;22s/^/set -x/n/;26s/^/set +x/n/'' myscript) args

agregará declare -p v1 v2 >&2 después de la línea 18, set -x antes de la línea 22 y set +x antes de la línea 26.

pequeña muestra:

bash <(sed ''2,3s/$//ndeclare -p LINENO i v2 >/&2/;5s/^/set -x/n/;7s/^/set +x/n/'' <( seq -f ''echo $@, $((i=%g))'' 1 8)) arg1 arg2 arg1 arg2, 1 arg1 arg2, 2 declare -i LINENO="3" declare -- i="2" /dev/fd/63: line 3: declare: v2: not found arg1 arg2, 3 declare -i LINENO="5" declare -- i="3" /dev/fd/63: line 5: declare: v2: not found arg1 arg2, 4 + echo arg1 arg2, 5 arg1 arg2, 5 + echo arg1 arg2, 6 arg1 arg2, 6 + set +x arg1 arg2, 7 arg1 arg2, 8

Nota: ¡ Cuidar acerca de $LINENO se verá afectado por modificaciones sobre la marcha !

(Para ver la secuencia de comandos resultante sin ejecución, simplemente suelte bash <( y ) arg1 arg2 )

Paso a paso, tiempo de ejecución

Echa un vistazo a mi respuesta sobre cómo crear perfiles de scripts Bash




Encontré la utilidad shellcheck y puede ser que algunas personas lo encuentren interesante https://github.com/koalaman/shellcheck

Un pequeño ejemplo:

$ cat test.sh ARRAY=("hello there" world) for x in $ARRAY; do echo $x done $ shellcheck test.sh In test.sh line 3: for x in $ARRAY; do ^-- SC2128: Expanding an array without an index only gives the first element.

arregla el error, primero intenta ...

$ cat test.sh ARRAY=("hello there" world) for x in ${ARRAY[@]}; do echo $x done $ shellcheck test.sh In test.sh line 3: for x in ${ARRAY[@]}; do ^-- SC2068: Double quote array expansions, otherwise they''re like $* and break on spaces.

Intentemoslo de nuevo...

$ cat test.sh ARRAY=("hello there" world) for x in "${ARRAY[@]}"; do echo $x done $ shellcheck test.sh

¡encuentra ahora!

Es solo un pequeño ejemplo.


Esta respuesta es válida y útil: share

Pero, considero que los métodos de depuración de scripts "estándar" son ineficaces, poco intuitivos y difíciles de usar. Para aquellos que utilizan sofisticados depuradores GUI que ponen todo a su alcance y simplifican el trabajo para problemas fáciles (y posibles problemas difíciles), estas soluciones no son muy satisfactorias.

Lo que hago es usar una combinación de DDD y bashdb. El primero ejecuta el último y el segundo ejecuta el script. Esto proporciona una interfaz de usuario de varias ventanas con la capacidad de desplazarse por el código en contexto y ver variables, apilar, etc., sin el esfuerzo mental constante para mantener el contexto en su cabeza o para volver a enumerar la fuente.

Hay una guía para configurarlo aquí: http://ubuntuforums.org/showthread.php?t=660223


Hay una gran cantidad de detalles sobre el inicio de sesión para scripts de shell a través de variables globales de shell. Podemos emular el tipo similar de inicio de sesión en el script de shell: http://www.cubicrace.com/2016/03/log-tracing-mechnism-for-shell-scripts.html

La publicación contiene detalles sobre la introducción de niveles de registro como INFO, DEBUG, ERROR. Detalles de rastreo como entrada de script, salida de script, entrada de función, salida de función.

Registro de muestra:


He usado los siguientes métodos para depurar mi script.

set -e hace que el script se detenga inmediatamente si cualquier programa externo devuelve un estado de salida distinto de cero. Esto es útil si su secuencia de comandos intenta manejar todos los casos de error y donde una falla al hacerlo debe quedar atrapada.

set -x se mencionó anteriormente y es sin duda el más útil de todos los métodos de depuración.

set -n también puede ser útil si desea verificar si su script tiene errores de sintaxis.

strace también es útil para ver qué está pasando. Especialmente útil si usted no ha escrito el guión usted mismo.


Instale VSCode , luego agregue la extensión de depuración bash y VSCode listo para depurar en modo visual. mira Here en acción.


También puede escribir "set -x" dentro del script.


Usa eclipse con los plugins sin cáscara y basheclipse.

https://sourceforge.net/projects/shelled/?source=directory https://sourceforge.net/projects/basheclipse/?source=directory

Para el bombardeo: descargue el zip e impórtelo en eclipse a través de la ayuda -> instale un nuevo software: archivo local Para basheclipse: copie los frascos en el directorio dropins del eclipse

Siga los pasos proporcionados https://sourceforge.net/projects/basheclipse/files/?source=navbar

Escribí un tutorial con muchas capturas de pantalla en http://dietrichschroff.blogspot.de/2017/07/bash-enabling-eclipse-for-bash.html


sh -x script [arg1 ...] bash -x script [arg1 ...]

Estos le dan un rastro de lo que se está ejecutando. (Ver también ''Aclaración'' cerca de la parte inferior de la respuesta.)

A veces, necesita controlar la depuración dentro del script. En ese caso, como me reminded Cheeto , puedes usar:

set -x

Esto activa la depuración. Luego puede apagarlo de nuevo con:

set +x

(Puede averiguar el estado de seguimiento actual analizando $- , los indicadores actuales, para x .)

Además, las shells generalmente proporcionan opciones '' -n '' para ''no ejecución'' y '' -v '' para ''verbose''; puede usarlos en combinación para ver si el intérprete de comandos cree que podría ejecutar su secuencia de comandos, ocasionalmente útil si tiene una cita desequilibrada en alguna parte.

Existe la opinión de que la opción '' -x '' en Bash es diferente de otras shells (ver los comentarios). El manual de Bash dice:

  • -X

    Imprima un rastro de comandos simples, for comandos, comandos de case , comandos de select y aritmética for comandos y sus argumentos o listas de palabras asociadas después de que se hayan expandido y antes de que se ejecuten. El valor de la variable PS4 se expande y el valor resultante se imprime antes del comando y sus argumentos expandidos.

Eso no parece indicar un comportamiento diferente en absoluto. No veo ninguna otra referencia relevante a '' -x '' en el manual. No describe las diferencias en la secuencia de inicio.

Aclaración : en sistemas como un cuadro Linux típico, donde '' /bin/sh '' es un enlace simbólico a '' /bin/bash '' (o donde se encuentre el ejecutable Bash), las dos líneas de comando logran el efecto equivalente de ejecutar el script con seguimiento de ejecución. En otros sistemas (por ejemplo, Solaris y algunas variantes más modernas de Linux), /bin/sh no es Bash, y las dos líneas de comando darían (ligeramente) diferentes resultados. En particular, '' /bin/sh '' sería confundido por construcciones en Bash que no reconoce en absoluto. (En Solaris, /bin/sh es un shell Bourne, en el Linux moderno, a veces es Dash, un shell más pequeño, estrictamente POSIX solamente). Cuando se invoca por su nombre de esta manera, la línea ''shebang'' ('' #!/bin/bash ''vs ''#!/bin/sh '') al comienzo del archivo no tiene ningún efecto sobre cómo se interpretan los contenidos.

El manual de Bash tiene una sección en modo Bash POSIX que, contrariamente a una versión antigua pero errónea de esta respuesta (ver también los comentarios a continuación), describe en detalle la diferencia entre ''Bash invocado como sh '' y ''Bash invocado como bash ''.

Al depurar un script de shell (Bash), será sensato y sensato, incluso necesario, para usar el shell nombrado en la línea shebang con la opción -x . De lo contrario, puede (¿tendrá?) Obtener un comportamiento diferente al depurar desde la ejecución del script.