Eu tenho um script que mede quanto tempo algum comando é executado.
Ele precisa do time
comando "real" , ou seja, um binário, por exemplo, em /usr/bin/time
(como o bash-built-in não possui o -f
sinalizador).
Abaixo, um script simplificado que pode ser depurado:
#!/bin/bash
TIMESEC=$(echo blah | ( /usr/bin/time -f %e grep blah >/dev/null ) 2>&1 | awk -F. '{print $1}')
echo ABC--$TIMESEC--DEF
if [ "$TIMESEC" -eq 0 ] ; then
echo "we are here!"
fi
Salve como "test.sh" e execute:
$ bash test.sh
ABC--0--DEF
we are here!
Então funcionou.
Agora, vamos tentar depurar isso adicionando "-x" à linha de comando do bash:
$ bash -x test.sh
++ echo blah
++ awk -F. '{print $1}'
+ TIMESEC='++ /usr/bin/time -f %e grep blah
0'
+ echo ABC--++ /usr/bin/time -f %e grep blah 0--DEF
ABC--++ /usr/bin/time -f %e grep blah 0--DEF
+ '[' '++ /usr/bin/time -f %e grep blah
0' -eq 0 ']'
test.sh: line 10: [: ++ /usr/bin/time -f %e grep blah
0: integer expression expected
Por que esse script é interrompido quando estamos usando "-x" e funciona bem sem ele?
bash
shell-script
Tomasz Chmielewski
fonte
fonte
-x
on, a$()
construção está-x
incluindo a saída como parte do valor resultante. Não sei se esse é o comportamento "esperado" ou um bug ... Ou talvez seja o subshell()
dentro que está realmente fornecendo a-x
saída.BASH_XTRACEFD
permite redirecionar aset -x
saída para um local com menos problemas.Respostas:
O problema é esta linha:
onde você está redirecionando o erro padrão para corresponder à saída padrão. O bash está gravando suas mensagens de rastreio no erro padrão e está (por exemplo) usando seus recursos internos
echo
junto com outras construções de shell, tudo no processo do bash.Se você mudar para algo como
contornará esse problema e talvez seja um compromisso aceitável entre rastreamento e trabalho:
fonte
você também pode simplesmente soltar o subshell. aparentemente, são as conchas aninhadas que acabam perturbando uma à outra:
Se você fizer:
... você termina com o subshell lançado para lidar com a seção do pipeline que hospeda o subshell dentro. Como o shell sem redireciona até a saída de depuração do subshell (como também faria com qualquer outro tipo de
{
comando composto que; } >redirect
você possa optar por usar) para sua seção do pipeline, você acaba misturando fluxos. Tem a ver com a ordem do redirecionamento.Em vez disso, se você simplesmente redirecionar apenas a saída de erro dos comandos que está tentando avaliar, e deixar que a saída do shell do host atinja o stderr, você não acabará com o mesmo problema.
e entao...
... o shell do host é livre para continuar escrevendo seu stderr onde quiser, enquanto redireciona apenas a saída dos comandos que chama no canal.
Por falar nisso ...
fonte