Provavelmente, a coisa mais fácil de fazer, se você não se importa em mesclar stdout e stderr, é executar com o -x
flag que faz o bash imprimir cada comando conforme ele é executado com um prefixo como +++
em que o número de caracteres vem do nível de aninhamento. Você pode então pós-processar a saída, lembrando o prefixo, mas suprimindo a linha, e aplicando-a a qualquer linha não pré-fixada seguinte, que será seu eco ou printf.
Por exemplo, pegue um pequeno script fatorial, myprog
:
#!/bin/bash
f(){
local i=$1
if [[ "$i" > 1 ]]
then echo $((i*$(f $((i-1)))))
else echo $i
fi
echo "my debug info $i" >&2
}
echo "factorial ${1?} is $(f $1)"
Executando com
bash -x myprog 4 |&
awk '/^+/{ indent=$1; next }
{ print indent " " $0 }'
te dá
+++++ my debug info 1
++++ my debug info 2
+++ my debug info 3
++ my debug info 4
+ factorial 4 is 24
Naturalmente, você pode obter resultados de depuração muito bons com números de linha, nomes de arquivos e funções apenas configurando PS4
com -x
. Por exemplo
PS4='+ ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]} - [${SHLVL},${BASH_SUBSHELL}, $?] '
oferece:
++ myprog:10: main - [2,1, 0] f 4
++ myprog:3: f - [2,1, 0] local i=4
++ myprog:4: f - [2,1, 0] [[ 4 > 1 ]]
+++ myprog:5: f - [2,2, 0] f 3
+++ myprog:3: f - [2,2, 0] local i=3
+++ myprog:4: f - [2,2, 0] [[ 3 > 1 ]]
++++ myprog:5: f - [2,3, 0] f 2
++++ myprog:3: f - [2,3, 0] local i=2
++++ myprog:4: f - [2,3, 0] [[ 2 > 1 ]]
...