Utilitário para armazenar em buffer uma quantidade ilimitada de dados em um pipeline?

12

Existe um utilitário que eu possa colocar em um pipeline para desacoplar as velocidades de leitura e gravação?

$ producer | buf | consumer

Basicamente, eu quero um utilitário buf que leia sua entrada o mais rápido possível, armazenando-o na memória, assim consumer pode levar seu tempo, enquanto producer é executado o mais rápido possível.

    
por Doctor J 03.10.2011 / 03:02

5 respostas

12

O utilitário pv (visualizador de canos) pode fazer isso (com a opção -B ) e muito mais, incluindo relatórios de progresso.

    
por 03.10.2011 / 06:12
9

você pode usar dd :

producer | dd obs=64K | consumer

Está disponível em todos os unix.

    
por 03.10.2011 / 13:58
7

Dê uma olhada no mbuffer . Pode armazenar em buffer para memória ou arquivo mapeado de memória ( -t / -T ).

    
por 03.10.2011 / 15:35
1

Esta é basicamente uma resposta negativa. Parece que nem dd , nem mbuffer , nem mesmo pv funciona em todos os casos, em particular se a taxa de dados gerada pelo produtor puder variar muito. Eu dou alguns testes abaixo. Depois de digitar o comando, aguarde cerca de 10 segundos e digite > (para ir até o final dos dados, ou seja, aguarde o final da entrada).

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | dd bs=64K | less

Aqui, depois de digitar > , é preciso esperar por 5 segundos, o que significa que o produtor (script zsh) bloqueou antes do sleep 5 . Aumentando o tamanho de bs para p. 32M não altera o comportamento, embora o buffer de 32MB seja grande o suficiente. Eu suspeito que isso é porque dd bloqueia a saída em vez de continuar com a entrada. Usar oflag=nonblock não é uma solução porque isso descarta dados.

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | mbuffer -q | less

Com mbuffer , o problema é que a primeira linha (foo0) não aparece imediatamente. Não parece haver nenhuma opção para ativar o buffer de linha na entrada.

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | pv -q -B 32m | less

Com pv , o comportamento é semelhante a dd . Pior, eu suspeito que ele faz coisas erradas no terminal, pois às vezes less não pode mais receber entrada do terminal; por exemplo, não se pode sair com q .

    
por 04.07.2014 / 20:48
0

Movimentação fora do padrão: usando buffers de soquete.

Exemplo:

# echo 2000000000 > /proc/sys/net/core/wmem_max
$ socat -u system:'pv -c -N i /dev/zero',sndbuf=1000000000 - | pv -L 100k -c -N o > /dev/null
        i:  468MB 0:00:16 [ 129kB/s] [  <=>                        ]
        o: 1.56MB 0:00:16 [ 101kB/s] [       <=>                   ]

Implementamos duas ferramentas adicionais para isso: buffered_pipeline e mapopentounixsocket

$ ./buffered_pipeline ! pv -i 10 -c -N 1 /dev/zero ! $((20*1000*1000)) ! pv -i 10 -L 100k -c -N 2 ! > /dev/zero
        1: 13.4MB 0:00:40 [ 103kB/s] [         <=>      ]
        2: 3.91MB 0:00:40 [ 100kB/s] [         <=>      ]
    
por 30.12.2015 / 23:08

Tags