O utilitário pv
(visualizador de canos) pode fazer isso (com a opção -B
) e muito mais, incluindo relatórios de progresso.
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.
O utilitário pv
(visualizador de canos) pode fazer isso (com a opção -B
) e muito mais, incluindo relatórios de progresso.
você pode usar dd
:
producer | dd obs=64K | consumer
Está disponível em todos os unix.
Dê uma olhada no mbuffer . Pode armazenar em buffer para memória ou arquivo mapeado de memória ( -t
/ -T
).
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
.
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] [ <=> ]