Redirecionamento e tubulação para grepping

1

Estou trabalhando em um script que executará um processo de soma de verificação que é enviado para STDOUT, que eu quero, então, para linhas que correspondem a OK ou FAILED e faço coisas diferentes com essas correspondências (ou seja, saída para terminal e log). Eu assisti uma tonelada de vídeos no Youtube e li muito sobre redirecionamento, mas eu simplesmente não consigo entender como exatamente o redirecionamento funciona. O que eu estou tentando fazer é encadear o STDOUT a vários greps sem que eles devorem o texto não correspondido.

Aqui está um conceito do que eu estou tentando usar cat em vez de md5sum com um arquivo de texto de nomes de animais em cada linha (DOG, CAT, PONY, RHINO, DEER, FOX):

{ cat test.txt 3>&1 | tee /dev/fd/3 | grep DOG; } 3> results.txt

Isso faz o que eu espero. O que eu entendo aqui é que eu estou fazendo um gato no arquivo e, em seguida, abrindo o fd3 que aponta para o que está escrito em STDOUT (fd1). Uma vez que o grep irá engolir tudo de fd1, eu tee o STDOUT de cat explicitamente para fd3 e depois canalizo o STDOUT para grep. Grep irá imprimir a linha correspondente DOG e, em seguida, todo o texto escrito para fd3 do cat será enviado para um arquivo results.txt.

Agora, para encadear outro grep para procurar por outro texto eu tenho que apontar os dados fd3 de volta para STDOUT, tee explicitamente de volta para fd3 e então canalizar STDOUT para um novo grep.

{ { cat test.txt 3>&1 | tee /dev/fd/3 | grep DOG; } 3>&1 | tee /dev/fd/3 | grep PONY; } 3> results.txt

O primeiro problema aqui é que o STDOUT do primeiro grep está sendo empurrado para o fd3 uma segunda vez ao invés de imprimir no terminal. Então agora o meu results.txt está ficando duplicado e eu nunca consegui imprimir nada na tela para o primeiro grep. É aqui que meu entendimento de redirecionamentos está desmoronando. Eu meio que entendo o que está acontecendo, mas não consigo descobrir uma solução simples.

Eu quero grep STDOUT, imprimir os resultados para a tela, e passar o texto original para outro grep, e talvez um terceiro, quarto, etc, sem modificar o texto original que estou passando para cada GREP e sem cada grep subseqüente comendo a partida anterior que deve ser impressa na tela.

Eu provavelmente poderia fazer isso armazenando uma variável e chamando-a em várias linhas de greps, mas depois tenho que esperar que o primeiro comando inteiro seja concluído. No caso do aplicativo em que estou trabalhando, quero ver os resultados em tempo real durante uma soma de verificação, não apenas uma tela em branco por uma hora, até que todo o processo seja concluído. Qualquer esclarecimento sobre o que estou fazendo de errado seria super útil, obrigado!

EDITAR

Eu entendo este uso exato de gato é inútil, eu usei apenas para demonstrar o conceito. No script que vou aplicar o conceito, o primeiro comando é realmente:

md5sum -c checksum.md5

Que lerá um arquivo de soma de verificação, re-hash a origem e saída para STDOUT uma linha de aprovação / reprovação. Eu quero então fazer o grep e enviar os resultados para separar os logs e / ou a saída do terminal - mas o cat pareceu ser uma maneira mais simples de demonstrar o problema, pois isso pode ser aplicado para filtrar qualquer comando e grepping do stream, como find, md5 , ls, etc.

    
por iceblueorbitz 13.01.2018 / 22:48

2 respostas

4

Você pode fazer melhor o que pede com a substituição do processo:

  1. Sendo o mais próximo possível do seu comando original:

    cat test.txt | tee >(grep DOG) >(grep PONY) >results.txt
    
  2. Removendo o uso inútil de gato:

    <test.txt tee >(grep DOG) >(grep PONY) >results.txt
    

    Ou:

    tee >(grep DOG) >(grep PONY) <test.txt >results.txt
    
por 13.01.2018 / 22:59
1

A solução de isaac é melhor, mas o seu caminho ficaria assim:

{ <input tee results.txt /dev/fd/3 | grep DOG >&2; } 3>&1 |
    { tee /dev/fd/3 | grep PONY >&2; } 3>/dev/null

ou por três

{ <input tee results.txt /dev/fd/3 | grep DOG >&2; } 3>&1 |
    { tee /dev/fd/3 | grep PONY >&2; } 3>&1 |
    { tee /dev/fd/3 | grep CAT >&2; } 3>/dev/null
    
por 14.01.2018 / 00:58