2016-03-05 38 views
12

Qual è il modo più pulito (più semplice, più efficiente, più breve, più rapido, più semplice, più elegante) per creare una pipeline non lineare come questa in Bash?Qual è il modo più pulito per creare una pipeline non lineare in Bash?

Ho tre comandi: mksock, irclogin e ircpingpong. Voglio tubo stdin, irclogin, e ircpingpong in mksock, e tubo mksock in stdout e ircpingpong. Ciò significa che mksock e ircpingpong sono in un ciclo. Ho disegnato un diagramma. Diagram

irclogin deve essere eseguito solo una volta e il primo ingresso in mksock. Successivamente, ircpingpong e stdin devono essere accettati in qualsiasi momento. Attualmente sto usando tubi e un file temporaneo come questo:

#!/bin/bash 

server=127.0.0.1 
port=6667 

infifo=/tmp/ircin 
outfifo=/tmp/ircout 
pongfifo=/tmp/ircpong 

rm $infifo 
rm $outfifo 
rm $pongfifo 
mkfifo $infifo 
mkfifo $outfifo 
touch $pongfifo 

(irclogin | cat - $infifo & tail -f $pongfifo;) | mksock $server $port | tee $outfifo | stdbuf -oL ircpingpong > $pongfifo & 
cat < $outfifo & 
cat > $infifo 
pkill tail 

Questo funziona, ma io voglio sapere se c'è un modo migliore per farlo. Mi infastidisce il fatto che sto usando un file piuttosto che un tubo per il looping da ircpingpong a mockock utilizzando la coda. Usare una pipe non ha funzionato perché, a mio modo di vedere, qualcosa è stato scritto nella pipe prima che tail -f inizi a leggerlo, e così non ce la fa. Mi infastidisce anche il fatto che devo uccidere la coda alla fine dello script, perché non si ferma da solo e lascerebbe il socket connesso anche dopo che lo script è terminato.

+2

Questo è ciò per cui Coprocesi sono. Sono supportati in modo diverso su shell Korn e bash, i coprocesses bash sono stati introdotti in bash 4.0. Vedi http://wiki.bash-hackers.org/syntax/keywords/coproc – cdarke

risposta

2

posso suggerire una versione senza file temporanei, e con due fifo-s:

fifo1=/tmp/fifo1 
fifo2=/tmp/fifo2 
rm $fifo1 
rm $fifo2 
mkfifo $fifo1 
mkfifo $fifo2 

ircpingpong < $fifo1 > $fifo2 & 
(mksock <$fifo2|tee $fifo1)& 
irclogin >$fifo2 & 
cat >$fifo2 

L'idea è quella di eseguire tutti i programmi a parte, e garantire solo che l'input e l'output di ogni programma viene reindirizzato correttamente secondo a questo diagramma:

pipe-flow

Naturalmente, ircpingpong deve leggere e scrivere stdinstdout, irclogin deve scrivere a 0.123.e mksock devono leggere da stdin e scrivere a stdout.