Normalmente, stdout
é buffer de linha. Em outras palavras, contanto que seu printf
argumento termine com uma nova linha, você pode esperar que a linha seja impressa instantaneamente. Isso não parece se manter ao usar um pipe para redirecionar tee
.
Eu tenho um programa C ++,, a
que produz strings, sempre \n
terminadas, para stdout
.
Quando é executado sozinho ( ./a
), tudo imprime corretamente e na hora certa, conforme o esperado. No entanto, se eu canalizá-lo para tee
( ./a | tee output.txt
), ele não imprimirá nada até que seja encerrado, o que anula o propósito de uso tee
.
Eu sei que poderia corrigir isso adicionando um fflush(stdout)
após cada operação de impressão no programa C ++. Mas existe uma maneira mais limpa e mais fácil? Existe um comando que posso executar, por exemplo, que forçaria o stdout
buffer de linha, mesmo ao usar um pipe?
expect
me compilar, poisunbuffer
não parece estar incluído por padrão no OS X.unbuffer
é apenas um pequeno script, então você não deve precisar recompilar o pacote inteiro../configure && make
demorou cerca de 10 segundos e depois mudeiunbuffer
para/usr/local/bin
:)unbuffer {commands with pipes/tee}
.podes tentar
stdbuf
(grande) parte da página de manual:
tenha isso em mente, porém:
você não está correndo
stdbuf
emtee
, você está executando-o ema
, de modo que este não deve afetá-lo, a menos que você defina o buffer dea
's correntes ema
' s fonte.Além disso, não
stdbuf
é POSIX, mas parte do GNU-coreutils.fonte
stdbuf
já está disponível nas distribuições Centos Linux que estamos usando, eunbuffer
não está. Obrigado!-u
para desativar o buffer no lado do python:python3 -u a.py | tee output.txt
Você também pode tentar executar seu comando em um pseudo-terminal usando o
script
comando (que deve forçar a saída do buffer de linha para o pipe)!Esteja ciente de que o
script
comando não propaga de volta o status de saída do comando encapsulado.fonte
script -t 1 /path/to/outputfile.txt ./a
funcionou muito bem para o meu caso de uso. Ele transmite ao vivo toda a saída aooutputfile.txt
mesmo tempo que a imprime no stdout do shell. Não precisava usartee
Você pode usar setlinebuf de stdio.h.
Isso deve alterar o buffer para "buffer de linha".
Se precisar de mais flexibilidade, você pode usar setvbuf.
fonte
setvbuf(stdout, NULL, _IOLBF, 0)
, o que é exatamente equivalente.Se você usar as classes de fluxo C ++ em vez disso, every
std::endl
será uma liberação implícita. Usando a impressão estilo C, acho que o método que você sugeriu (fflush()
) é a única maneira.fonte
#include <iostream> #include <unistd.h> int main(void) { std::cout << "1" << std::endl; sleep(1); std::cout << "2" << std::endl; }
. endl sempre limpa o buffer conforme definido aqui: en.cppreference.com/w/cpp/io/manip/endl