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

47

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

Se eu redirecionar para a saída para um arquivo '> out.txt 'Eu recebo toda a saída, mas ela é armazenada em buffer, então não consigo mais ver o que está fazendo agora.

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

    
por James Dean 26.07.2011 / 16:34

8 respostas

47

Você pode definir explicitamente as opções de buffer dos fluxos padrão usando uma chamada setvbuf em C (consulte este link ), mas se você estiver tentando modificar o comportamento de um programa existente, tente stdbuf (parte de coreutils começando com a versão 7.5 aparentemente).

Isso armazena em buffer stdout até uma linha:

stdbuf -oL command > output

Isso desativa totalmente o buffer stdout :

stdbuf -o0 command > output
    
por 27.07.2011 / 17:41
8

Você pode obter uma saída de buffer de linha para um arquivo usando o comando script da seguinte forma:

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
    
por 31.01.2013 / 16:13
7

No Ubuntu, o pacote unbuffer (do pacote expect-dev ) fez o truque para mim. Basta executar:

unbuffer your_command

e não irá armazená-lo em buffer.

    
por 18.02.2013 / 12:48
4

A solução mais fácil que encontrei (não precisei de nenhum pacote de terceiros instalado) foi mencionada em um tópico semelhante no Unix & Linux site: use o comando script . É 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 comando script é o arquivo de log a ser gravado . Se você simplesmente executar script -q your_command , sobrescreverá o comando que você indentou para executar com o arquivo de log. Verifique man script , por segurança, antes de tentar.

    
por 17.04.2014 / 05:57
2

experimente o comando script ; se o seu sistema o tiver, é necessário um nome de arquivo como argumento, todo o texto descartado para stdout é copiado para o arquivo. É muito útil quando um programa de instalação requer interação.

    
por 26.07.2011 / 16:49
2

Pessoalmente, prefiro a saída de piping de um comando que desejo examinar por meio de tee .

script registra muitas informações, incluindo o tempo de pressionamento de teclas e muitos caracteres não imprimíveis. O que tee salva é muito mais legível para mim.

    
por 26.07.2011 / 16:51
1

Redirecione a saída para um arquivo e siga o arquivo com o comando tail -f .

Editar

Se isso ainda sofrer de 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 lote for executado em uma linguagem de script, deve haver um recurso de registro de qualquer maneira.

    
por 26.07.2011 / 18:47
0

Você pode usar o comando tee , apenas mágica!

someCommand | tee logFile.log ambos serão exibidos no console e gravados no arquivo de log.

    
por 26.04.2013 / 14:32