Existe uma maneira de redirecionar a saída para um arquivo sem armazenar em buffer no unix / linux?


49

Eu tenho um processo em lote de longa execução que gera algumas informações de depuração e processo para o stdout. Se eu apenas correr de um terminal, posso rastrear 'onde está', mas os dados ficam demais e rolam para fora da tela.

Se eu redirecionar para a saída para um arquivo '> out.txt', obtenho a saída inteira eventualmente, mas ela é armazenada em buffer, para que eu não possa mais ver o que está fazendo no momento.

Existe uma maneira de redirecionar a saída, mas fazer com que ela não armazene em buffer suas gravações?


11
Você poderia, por favor, dar uma olhada no meu "debate" (e no @cnst) abaixo, acho que a única coisa que você deseja é ver a saída ao mesmo tempo em que a registra em um arquivo. Se você encontrou uma solução, informe-nos;)!
— Benj

Respostas:


52

Você pode definir explicitamente as opções de buffer dos fluxos padrão usando uma setvbufchamada em C (consulte este link ), mas se estiver tentando modificar o comportamento de uma tentativa de programa existente stdbuf(parte da coreutilspartida da versão 7.5 aparentemente).

Isso armazena stdoutem buffer até uma linha:

stdbuf -oL command > output

Isso desativa stdoutcompletamente o buffer:

stdbuf -o0 command > output

aaarghhh ... Meu Ubuntu tem apenas 7,4 coreutils ... :(
— Calmarius

@ Calmarius: compilar coreutils deve ser bastante fácil. Basta pegar uma nova versão em ftp.gnu.org/gnu/coreutils e experimentar . É ./configure && maketarifa padrão . Você nem precisa instalá-lo depois, basta usar o stdbufbinário desativado src/.
— Eduardo Ivanec

argh duplo. Eu preciso disso em um velho centos distro e OSX, bem como no Ubuntu.
— Edk750


Existe uma maneira de forçar os buffers pipe / printf externamente para o processo em execução com PID conhecido?
— Mvorisek

9

Você pode obter saída com buffer de linha para um arquivo usando o scriptcomando da seguinte maneira:

stty -echo -onlcr   # avoid added \r in output
script -q /dev/null batch_process | tee output.log        # Mac OS X, FreeBSD
script -q -c "batch_process" /dev/null | tee output.log   # Linux
stty echo onlcr

-1 porque: a) diferentemente da resposta aceita, isso não funciona se você deseja executar o comando em segundo plano (o comando termina imediatamente sem concluir batch_processse você anexa &ao comando acima, pelo menos na minha caixa Linux), o que parece como um caso de uso extremamente comum eb) não há explicação aqui sobre como esse encantamento funciona.
— Mark Amery

8

No Ubuntu, o pacote do unbufferprograma (o expect-dev) fez o truque para mim. Apenas corra:

unbuffer your_command

e não vai amortecê-lo.


6

A solução mais fácil que encontrei (não precisava de pacotes de terceiros instalados) foi mencionada em um tópico semelhante no site do Unix e Linux : use o scriptcomando É antigo e provavelmente já está instalado.

$ script -q /dev/null long_running_command | print_progress       # FreeBSD, Mac OS X
$ script -q -c "long_running_command" /dev/null | print_progress  # Linux

Observe que o primeiro parâmetro de nome de arquivo para o scriptcomando é o arquivo de log a ser gravado . Se você simplesmente executar script -q your_command, substituirá o comando que recuou para executar com o arquivo de log. Verifique man script, para estar seguro, antes de tentar.


4

tente o scriptcomando; se o seu sistema possui, ele recebe um nome de arquivo como argumento, todo o texto despejado no stdout é copiado para o arquivo. É muito útil quando um programa de instalação requer interação.


Eu sei do truque 'script -a out.txt'. Fiquei me perguntando se existe alguma outra maneira de tornar o processo de gravação sem buffer.
— James Dean

3

Pessoalmente, prefiro canalizar a saída de um comando que quero examinar tee.

scriptregistra muitas informações, incluindo o tempo das teclas pressionadas e muitos caracteres não imprimíveis. O que teeeconomiza é muito mais legível para mim.


Eu também adicionaria "| less" à linha de comando.
— HUB

4
Tenho certeza de que isso também teeé afetado pelo buffer. Frequentemente, ainda recebo linhas parciais exibidas por tee ao dividir a saída dos findcomandos.
— Magellan

2

Redirecione a saída para um arquivo e siga o arquivo com o tail -fcomando

Editar

Se isso ainda sofrer buffer, use o recurso syslog (que geralmente é sem buffer). Se o processo em lote for executado como um script de shell, você poderá usar o comando logger para fazer isso. Se o trabalho em lotes for executado em uma linguagem de script, deve haver um recurso de registro de qualquer maneira.


3
É isso que eu faço agora, mas o processo armazena em buffer a gravação no arquivo e é exatamente isso que eu quero evitar.
— James Dean

Veja minha edição para uma proposta atualizada.
— 27611 Wolfgangsz

11
Isso não funciona por razões óbvias. Quem diabos dá This answer is usefulrespostas que não funcionam e que não podem funcionar?
— CNST

1

Você pode usar o teecomando, apenas mágica!

someCommand | tee logFile.logserá tanto visor no console e escrever no arquivo de log.


Não funciona teenão impedirá a realização de buffer.
— CNST

11
@cnst Efetivamente, teenão evitará alguns buffers, mas apenas permitirá que você dê uma olhada no que é a saída. Era isso que @JamesDean queria (como eu subestime sua pergunta), mas acho que o buffer não é realmente o problema aqui. Se você tiver mais detalhes, me avise.
— Benj

Ele queria ver a saída, e ele não está obtendo nenhuma saída (de uma maneira sem buffer), e ainda assim você sugere usar teepara obter uma melhor visualização da saída que não está recebendo?
— CNST

11
Como eu redijo a pergunta @JamesDean: "Eu redireciono para a saída para um arquivo '> out.txt'" significa para mim nenhuma saída do console, aguarde a conclusão do processo enquanto toda a saída é redirecionada. Quando você está usando >, não vê nada no console. Eu acho que @ JamesDean está usando a palavra "buffering" para descrever isso. Vou postar um comentário em sua pergunta para ele dizer mais sobre o que ele quer.
— Benj
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.