GNU/Linux >> Tutoriales Linux >  >> Linux

Rastreo de programas ejecutados llamados por un script Bash

Un guión sencillo que escribí hace unos días...

# FILE       : sctrace.sh
# LICENSE    : GPL v2.0 (only)
# PURPOSE    : print the recursive callers' list for a script
#              (sort of a process backtrace)
# USAGE      : [in a script] source sctrace.sh
#
# TESTED ON  :
# - Linux, x86 32-bit, Bash 3.2.39(1)-release

# REFERENCES:
# [1]: http://tldp.org/LDP/abs/html/internalvariables.html#PROCCID
# [2]: http://linux.die.net/man/5/proc
# [3]: http://linux.about.com/library/cmd/blcmdl1_tac.htm

#! /bin/bash

TRACE=""
CP=$$ # PID of the script itself [1]

while true # safe because "all starts with init..."
do
        CMDLINE=$(cat /proc/$CP/cmdline)
        PP=$(grep PPid /proc/$CP/status | awk '{ print $2; }') # [2]
        TRACE="$TRACE [$CP]:$CMDLINE\n"
        if [ "$CP" == "1" ]; then # we reach 'init' [PID 1] => backtrace end
                break
        fi
        CP=$PP
done
echo "Backtrace of '$0'"
echo -en "$TRACE" | tac | grep -n ":" # using tac to "print in reverse" [3]

... y una prueba sencilla.

Espero que les guste.


~$ help caller
caller: caller [EXPR]
    Returns the context of the current subroutine call.

    Without EXPR, returns "$line $filename".  With EXPR,
    returns "$line $subroutine $filename"; this extra information
    can be used to provide a stack trace.

    The value of EXPR indicates how many call frames to go back before the
    current one; the top frame is frame 0.

Puede usar Bash Debugger http://bashdb.sourceforge.net/

O, como se mencionó en los comentarios anteriores, el caller bash incorporado. Ver:http://wiki.bash-hackers.org/commands/builtin/caller

i=0; while caller $i ;do ((i++)) ;done

O como una función bash:

dump_stack(){
    local i=0
    local line_no
    local function_name
    local file_name
    while caller $i ;do ((i++)) ;done | while read line_no function_name file_name;do echo -e "\t$file_name:$line_no\t$function_name" ;done >&2
}

Otra forma de hacerlo es cambiar de PS4 y habilitar xtrace:

PS4='+$(date "+%F %T") ${FUNCNAME[0]}() $BASH_SOURCE:${BASH_LINENO[0]}+ '
set -o xtrace    # Comment this line to disable tracing.

Linux
  1. ¿Cómo depurar un script Bash?

  2. Bash Echo ¿La línea de comando se ejecutó en la propia línea de comando (no en un script)?

  3. Typeset -a ¿Está dando un error en el script?

  4. Bash Script para completar una plantilla?

  5. ¿Instalar programas desde el script Bash?

35 ejemplos de secuencias de comandos Bash

Cómo ejecutar un script Bash

¿Se puede conectar un script Bash a un archivo?

Ejecutar script bash desde URL

nombre base con espacios en un script bash?

Coincidencia de patrón de secuencia de comandos Bash