Usando o tempo limite do GNU ao redirecionar o stdout para o arquivo

2

Suponha que eu tenha um executável para o qual eu queira registrar STDOUT e STDERR para separar arquivos, da seguinte forma:

python write.py > out 2> err

Quando eu uso este comando com o GNU timeout , meu arquivo out está sempre vazio. Por que isso acontece e como posso corrigir isso?

timeout 5s python write.py > out 2> err

Exemplo write.py:

#!/bin/bash
import sys, time

i = 0
while True:    
    print i
    print >> sys.stderr, i
    time.sleep(1)
    i += 1
    
por jaynp 06.04.2015 / 07:16

1 resposta

4
$ timeout 5s python write.py > out 2> err
$ ls -l out err
-rw-r--r-- 1 yeti yeti 10 Apr  6 08:12 err
-rw-r--r-- 1 yeti yeti  0 Apr  6 08:12 out
$ timeout 5s python -u write.py > out 2> err
$ ls -l out err
-rw-r--r-- 1 yeti yeti 10 Apr  6 08:13 err
-rw-r--r-- 1 yeti yeti 10 Apr  6 08:13 out
$ cmp err out && echo same
same
$ cat out 
0
1
2
3
4

python usa gravações armazenadas em buffer em stdout , mas não em stderr . Então tudo escrito em sys.stderr é escrito imediatamente, mas o conteúdo de sys.stdout é mantido em um buffer até que o buffer esteja cheio para minimizar as operações de gravação. Dentro de 5 segundos, o buffer não preenche o suficiente para ser gravado uma única vez e timeout finaliza o interpretador python .

Adicionando a opção -u à invocação de python , as gravações em stdout também serão descompactadas.

Você pode forçar o mesmo comportamento para um programa Python definindo a variável de ambiente PYTHONUNBUFFERED . Para outros programas, você pode usar unbuffer do expectar ou stdbuf de GNU coreutils (veja Desativar o buffer no tubo ).

    
por 06.04.2015 / 08:23