Contar o número de bytes canalizados de um processo para outro

13

Estou executando um script de shell que envia dados de um processo para outro

process_a | process_b

Alguém sabe uma maneira de descobrir quantos bytes foram passados entre os dois programas? A única solução em que posso pensar no momento seria escrever um pequeno programa c que leia stdin, escreva para stdout e conte todos os dados transferidos, armazenando a contagem em uma variável de ambiente, como:

process_a | count_bytes | process_b

Alguém tem uma solução melhor?

    
por Simon Hodgson 18.12.2009 / 10:17

4 respostas

12

Passe pelo dd. a entrada padrão do dd é stdin e a saída padrão é stdout; quando terminar o I / O stdin / stdout, ele irá reportar ao stderr quanto os dados foram transferidos.

Se você deseja capturar a saída de dd e os outros programas já falam com stderr, use outro descritor de arquivo. Por exemplo,

$ exec 4>~/fred
$ input-command | dd 2>&4 | output-command
$ exec 4>&-
    
por 18.12.2009 / 13:04
25

Use pv o visualizador de canais. É uma ótima ferramenta. Uma vez que você saiba sobre isso, você nunca saberá como você viveu sem ele.

Ele também pode mostrar uma barra de progresso e a "velocidade" de transferência.

    
por 18.12.2009 / 10:26
6

process_a | tee >(process_b) | wc --bytes pode funcionar. Você pode redirecionar a contagem de wc para onde você precisar. Se process_b produzir alguma coisa para stdout / stderr , você provavelmente precisará redirecionar isso para algum lugar, se apenas /dev/null .

Para um exemplo ligeiramente inventado:

filestore:~# cat document.odt | tee >(dd of=/dev/null 2>/dev/null) | wc --bytes
4295

A título de explicação: tee permite direcionar a saída para vários arquivos (mais stdout) e a >() construct é a "substituição de processo" do bash, o que faz com que um processo pareça um arquivo somente de gravação. pode redirecionar para processos e arquivos (consulte aqui ou esta questão + resposta para um exemplo de usar tee para enviar saída para muitos processos) .

    
por 18.12.2009 / 11:22
1

Eu sei que estou atrasado para a festa, mas acredito que tenho uma boa resposta que pode melhorar esse segmento útil.
Esta é uma mistura de respostas de @Phil P e @David Spillett, mas:

  • diferentemente do @Phil P, evita criar um novo arquivo
  • diferentemente do @David Spillett, ele mantém a estrutura de pipeline

A contagem de bytes é impressa no stdout, junto com qualquer saída de process_b. Você pode usar um prefixo para identificar a linha contendo bytes ao trabalhar com a saída ( Bytes: no exemplo).

exec 3>&1
process_a | tee >({ echo -n 'Bytes:'; wc -c; } >&3) | process_b
exec 3>&-

AVISO:
Não confie na ordem das linhas na saída | A ordem é imprevisível e sempre pode ser diferente, mesmo ao chamar o mesmo script com os mesmos parâmetros!

    
por 20.03.2016 / 14:25

Tags