Dividir saída e reingressar novamente com pipes nomeados no linux

0

A minha pergunta está relacionada com link mas com uma configuração um pouco mais complicada.

Eu tenho três programas, cmd1 , cmd2 e cmd3 ;

cmd1 não recebe nenhuma entrada e grava no stdout

cmd2 lê stdin ou um determinado arquivo e grava em stdout

cmd3 lê dois arquivos

O fluxo de dados para esses programas é o seguinte: cmd2 consome dados produzidos por cmd1 e cmd3 consome dados produzidos por cmd1 e cmd2 :

cmd1 ---+-----> cmd2 --->
        |                  cmd3
        +---------------> 

Como posso conseguir esse fluxo de dados com uma única linha de comando usando > (), pipes e tee ?

Meu melhor palpite é cmd1 | tee >(cmd2) > >(cmd3) .

    
por bose 22.06.2018 / 19:50

1 resposta

3
mkfifo thepipe
cmd3 <( cmd1 | tee thepipe ) <( cmd2 thepipe )

Isso usa um canal nomeado, thepipe , para transferir dados entre tee e cmd2 .

Usando seu diagrama:

cmd1 ---(tee)---(thepipe)--- cmd2 --->
          |                            cmd3
          +-------------------------->

Exemplo com

  • cmd1 = echo 'hello world' , grava uma string na saída padrão.
  • cmd2 = rev , inverte a ordem dos caracteres em cada linha, lê um arquivo ou da entrada padrão.
  • cmd3 = paste , recebe entrada de dois arquivos (neste caso) e produz duas colunas.
mkfifo thepipe
paste <( echo 'hello world' | tee thepipe ) <( rev thepipe )

Resultado:

hello world     dlrow olleh

O mesmo, mas colocando o pipe nomeado na outra ramificação em seu diagrama:

cmd1 ---(tee)--------------- cmd2 --->
          |                            cmd3
          +-----(thepipe)------------>
cmd3 thepipe <( cmd1 | tee thepipe | cmd2 )

Com nossos comandos de exemplo:

paste thepipe <( echo 'hello world' | tee thepipe | rev )

Isso produz a mesma saída acima.

Existem obviamente outras possibilidades, como

cmd1 | tee >( cmd2 >thepipe ) | cmd3 /dev/stdin thepipe

mas eu não acho que você pode ficar longe de ter que usar um pipe nomeado, a menos que você esteja feliz escrevendo resultados intermediários em um arquivo temporário e dividindo-o em dois conjuntos de comandos.

    
por 22.06.2018 / 23:17

Tags