Como salvar o stdout e o stderr em um arquivo enquanto ainda vê a saída?

0

Estou tentando depurar um programa que gera muitos dados. Mas o evento que eu quero depurar acontece após um período aleatório de tempo (não posso forçá-lo). Então eu precisaria ver o stdout e stderr no meu shell e salvar a mesma saída em um arquivo para análise posterior e interromper assim que eu ver o que eu preciso na saída do meu shell.

Eu encontrei o comando script neste pergunte ao thread do Ubuntu mas não consigo fazê-lo funcionar, o script diz:

$ script "./client -p 4242 -n test"
Script started, output file is ./client -p 4242 -n test

e depois sai. O arquivo contém:

Script started on Thu Jun 26 13:51:12 2014

Script done on Thu Jun 26 13:51:12 2014

Portanto, script não funciona . O arquivo ./client é um script python. Eu também tentei lançá-lo com $ python client -p 4242 -n test , mas também não está funcionando.

Eu também vi no mesmo thread algumas respostas com tee e um pipe, mas não consigo extrair para o meu shell e ver o que está acontecendo:

$ ./client -p 4242 -n test | tee output.log

me dá um cursor de espera sem nada acontecer. Portanto, tee não funciona .

Existe alguma outra solução ou estou condenado a esperar e interromper o programa depois de algum tempo e espero que ele tenha passado pelo evento que estou procurando?

Muito obrigado pela sua ajuda!

P.S. Eu estou em zshell (com oh-meu-zsh), Mac OSX 10.9.3, Python 2.7.5

EDIT: posso ter que mencionar que estou usando o módulo multiprocessing e o script ./client lança vários outros Process es. Poderia ser por esse motivo? Ainda não entendi porque não vai pegar a saída do processo ./client ...

EDIT2: Eu tentei a resposta de Matteo abaixo (muito obrigado pela sua ajuda) e ela fica cada vez mais estranha e estranha:

Se o processo falhar (o servidor está desligado), posso ver a saída:

$ ./client -p 4242 -n test 2>&1 | tee output.log
Process Process-1:
Client # 1: Could not connect to server. Stopping.
Spawner: New client # 1 started...
Done.
$

mas se parece que está em execução, não vejo nada:

$ ./client -p 4242 -n test 2>&1 | tee output.log
^C [voluntary interrupt after a lot of waiting]
$ cat output.log
$ 

No log acima (onde ele falha), você pode ver que o novo processo imprime antes do principal ( Spawner ) mesmo que tenha sido iniciado após ele. Então parece uma mágica de saída muito estranha.

    
por achedeuzot 26.06.2014 / 14:00

2 respostas

2

Você pode redirecionar o erro padrão para a saída padrão e, em seguida, usar tee para duplicar o padrão saída e armazená-lo em um arquivo.

$ ./client -p 4242 -n test 2>&1  | tee output.log

Editar : você pode experimentar o comando

$ ( echo "stdout" ; echo "stderr" 1>&2 ) 2>&1  | tee output.log

Os dois echo s produzem a saída em stdout e stderr. Você deve ver ambos, e o mesmo em output.log

Editar

Em vez de modificar seu programa (flush), você também pode tentar script -q ou várias outras ferramentas, como mencionado em Desativar o buffer no tubo

    
por 26.06.2014 / 14:08
1

Vitória!

Como mencionado na pergunta, eu estava usando multiprocessing.Process do python para gerar novos processos do cliente principal. Por causa disso, a saída foi armazenada em buffer e esperou que o buffer ficasse cheio antes da limpeza, mas parece que isso nunca acontece com o comando | tee . Assim, nunca imprimindo nada e esperando sem parar.

Assim, a solução é adicionar um sys.stdout.flush() após cada print declaração , conforme mencionado aqui :

print "Player # " + int(self.id) + " joined the map"
sys.stdout.flush() #<==== THIS MAKES IT ALL WORK !

Depois disso, a resposta de Matteo funciona como um encanto e é possível ter a saída no shell e no arquivo de texto ao mesmo tempo.

$ ./client -p 4242 -n test 2>&1  | tee output.log'
$ cat output.log
Player # 1 joined the map.
Player # 1 updated it's inventory.
[...]
    
por 26.06.2014 / 17:49

Tags