Como posso usar o sed para editar a saída de depuração do bash? (bash -x)

6
#!/bin/bash -x
echo This is a script that has debugging turned on

Este script gera

+ echo This is a script that has debugging turned on
This is a script that has debugging turned on

Eu quero me livrar desses +s excluindo-os ou substituindo-os. Eu esperava que o sed pudesse corrigir meu problema ( sed 's/^\++//g' ) - Mas essa abordagem não afeta as linhas de saída de depuração.

Com mais algumas experiências, descobri que a saída de depuração parece estar sendo gravada em stderr (inferi isso com o comando ./test.sh 2>/dev/null , que a saída então exclui as linhas de depuração)

Com essa nova informação, esperaria que isso funcionasse ./test.sh 2>&1 | sed 's/^\++//g'

Mas, infelizmente, ainda recebo a mesma saída indesejada:

+ echo This is a script that has debugging turned on
This is a script that has debugging turned on
    
por aitee 23.10.2018 / 19:51

3 respostas

15

O + é o prompt PS4 . Defina-o como uma string vazia:

#!/bin/bash

PS4=''
set -x

echo 'This is a script that has debugging turned on'

Teste:

$ bash script.sh
echo 'This is a script that has debugging turned on'
This is a script that has debugging turned on

Ou, com o seu script original, defina PS4 como uma string vazia para o script ao invocá-lo:

$ PS4='' ./script.sh
echo This is a script that has debugging turned on
This is a script that has debugging turned on

Isso pode ser usado para inserir um timestamp:

$ PS4='$(date +"%T: ")' ./script.sh
21:08:19: echo 'This is a script that has debugging turned on'
This is a script that has debugging turned on
21:08:19: echo 'Now sleeping for 2 seconds'
Now sleeping for 2 seconds
21:08:19: sleep 2
21:08:21: echo Done
Done
    
por 23.10.2018 / 21:02
6

A principal limitação que você está enfrentando é que + é um recurso de expressão regular estendida , portanto, será necessário ativar a funcionalidade de expressão regular estendida; com a maioria dos sed s, que está com o sinal -E :

./test.sh 2>&1 | sed -E 's/^\++ //'

Eu fiz duas outras alterações:

  • adicionou um espaço à direita, para que os comandos depurados sejam exibidos à esquerda
  • removeu o sinalizador /g , pois a regex está ancorada, pode haver apenas uma correspondência por linha
por 23.10.2018 / 20:06
5

Você pode redirecionar o stderr para uma substituição de processo. No entanto, isso pode afetar a ordem da saída:

$ bash -x -c 'hostname; echo "$(date)"'
+ hostname
jackmanVM
++ date
+ echo 'Tue Oct 23 15:22:02 EDT 2018'
Tue Oct 23 15:22:02 EDT 2018

$ bash -x -c 'hostname; echo "$(date)"' 2> >(sed -E 's/^\++/debug: /')
debug:  hostname
jackmanVM
debug:  date
Tue Oct 23 15:22:35 EDT 2018
debug:  echo 'Tue Oct 23 15:22:35 EDT 2018'
    
por 23.10.2018 / 21:21