Possível modelar / sobrescrever STDOUT?

0

Eu estou depurando uma pilha de chamadas e simplesmente exibindo echo declarações de vários arquivos. Os logs simples estão se tornando um pouco difíceis de serem seguidos, então estou curioso para saber qual é a melhor maneira de aninhar a saída.

Eu pensei que configurar uma variável de ambiente para o número de guias ou como uma cadeia de espaço / tabulação de prefixo poderia ser a opção mais fácil se eu pudesse sobrecarregar o fluxo STDOUT. Basicamente, seria bom se eu pudesse fazer algo como STDOUT="$TABS$STDOUT" para manter empilhamento de caracteres de tabulação no início do fluxo de saída.

Mas eu não sabia se seria possível substituir o fluxo? Por exemplo, se eu quisesse prefixar cada linha com um hífen + espaço, isso é possível?

Tal que:

echo foo
echo bar
echo foobar

Produz:

- foo
- bar
- foobar
  1. É possível STDOUT de template?
  2. Qual é o método sugerido para saída de aninhamento, sem ter que modificar todas as instruções echo / printf nos vários scripts que podem ser chamados?
por BotNet 24.10.2016 / 21:49

1 resposta

0

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 ]]
...
    
por 26.10.2016 / 19:29