Tubulação nomeada bufferizada não bloqueada?

19

Eu estou procurando por algo que eu suspeito que não existe: Um canal nomeado buffer não-bloqueante (fifo) para uso na linha de comando. Existe tal coisa?

Aqui está o caso de uso: suponha que eu tenha um processo que será executado por muito tempo em segundo plano e espalhe muitos resultados em stdout . Eu realmente não me importo com a saída e não quero armazená-la (talvez eu não tenha espaço suficiente para), mas eu gostaria de "entrar" periodicamente e seguir o que está fazendo, depois desistir novamente e deixe-o fazer seu trabalho. Então, eu gostaria de redirecionar sua saída para esse pipe denominado de buffer não bloqueado teórico e, em seguida, tocar periodicamente nele.

Então basicamente eu quero começar assim ( 10M sendo o tamanho do buffer):

mkmagicfifo magicfifo 10M
spewingprocess > magicfifo &

... e periodicamente aparece para ver o que está acontecendo ...

tail -f magicfifo

... sem magicfifo armazenando toda a saída (portanto, não um arquivo normal), e sem bloqueando o processo de spewing quando ele é preenchido e isn não tocou (assim, não é bem normal um pipe nomeado).

Eu não acho que soluções envolvendo tail ou prune o façam (bem, eu posso pensar em uma solução envolvendo tail ), porque tail ainda exigiria que eu armazenasse todos os dados em algum lugar ( se eu quiser entrar e sair de olhar para ele), e prune tem que reescrever o arquivo, presumivelmente (eu admito que eu não tentei / provou isso) quebrando o redirecionamento do processo gerando toda a saída .

Espero poder escrever algum utilitário para fazer isso, mas * nix tem tantos aspectos legais de arquivos e cachimbos e tal, eu simplesmente não posso ajudar, mas acho que isso existe e eu simplesmente não não sei sobre isso.

Então: Existe tal coisa e, em caso afirmativo, o que é isso?

    
por T.J. Crowder 28.10.2011 / 16:25

3 respostas

15

Acho que o que você está procurando é o GNU screen . Ele mantém um buffer para manter a última tela cheia ou duas saídas de um ou mais programas e permite desconectar e voltar mais tarde.

    
por 28.10.2011 / 17:09
5

Você pode usar pv , ele fornece o máximo de armazenamento em buffer que você deseja em um pipeline. Você pode usá-lo assim:

sprewingprocess | pv -B 1g > ordinaryfifo &

Isso forneceria até 1 GB de buffer entre spewingprocess e o fifo. A maioria das distribuições Linux oferece pv em um pacote chamado, acredite ou não, pv .

    
por 29.10.2011 / 04:57
1

Eu tive o mesmo problema. Esta é minha primeira solução. Primeiro, grave a saída em um arquivo que truncamos após cada linha para que não cresça indefinidamente:

spewingprocess | while read line; do echo $line > buffer.txt ; done

Em seguida, leia o arquivo usando tail (onde 2> /dev/null se livra da mensagem de erro "arquivo truncado"):

tail -f ./buffer.txt 2> /dev/null

Desta forma, o buffer não cresce e podemos multiplexar, e. Corra quantas caudas quisermos. No entanto, o problema com essa abordagem é que podemos perder dados quando truncamos mais rápido do que a cauda pode ler como este teste mostra:

for ((i=0; ; i++)) ; do echo "$i" ; done | while read line; do  echo $line > buffer.txt ; done
tail -f ./buffer.txt 2> /dev/null > log.txt

Após a execução por algum tempo, a primeira e a última linha são:

$ head -n 1 log.txt
0
$ tail -n 1 log.txt
78783

Mas o arquivo tem menos linhas, então algumas são perdidas:

$ wc log.txt
67087  67087 392819 log.txt

Ainda assim, parece uma boa solução se você não se importa tanto com a perda de dados ou quando o processo de spewing não é rápido o suficiente para que ocorram perdas de dados.

    
por 07.02.2013 / 19:38