Sto lavorando su una pipeline che ha alcuni punti di ramificazione che in seguito merge-- sembrano qualcosa di simile:Come posso dividere e ricongiungere STDOUT da più processi?
command2
/ \
command1 command4
\ /
command3
Ogni comando scrive su STDOUT e accetta l'input via STDIN. STDOUT dal comando 1 deve essere passato a sia a sia a comando2 e comando3, che vengono eseguiti in sequenza e il loro output deve essere effettivamente concatenato e passato a command4. Inizialmente ho pensato che qualcosa di simile potrebbe funzionare:
$ command1 | (command2; command3) | command4
che non funziona, però, come solo STDOUT da comando2 viene passato al comando 4, e quando rimuovo Command4 è evidente che Command3 non viene superato il flusso appropriato da command1 - in altre parole, è come se command2 stia esaurendo o consumando il flusso. Ottengo lo stesso risultato con {command2; comando3; } nel mezzo pure. Così ho pensato che dovrei usare 'tee' with process substitution, e provato questo:
$ command1 | tee >(command2) | command3 | command4
Ma sorprendentemente che non ha funzionato sia - sembra che l'uscita del command1 e l'output di comando2 sono convogliato in Command3, che genera errori e solo l'output di command3 viene convogliato in command4. Ho trovato che il seguente ottiene l'input e l'output appropriato da e per command2 e Command3:
$ command1 | tee >(command2) >(command3) | command4
Tuttavia, questo torrenti l'uscita di Command1 Command4 pure, che porta a problemi come command2 e Command3 produrre una diversa specifica di comando1. La soluzione che ho arrivato sembra hacky, ma funziona:
$ command1 | tee >(command2) >(command3) > /dev/null | command4
che sopprime command1 passando la sua uscita a Command4, mentre la raccolta STDOUT da command2 e Command3. Funziona, ma mi sento come se mi mancasse una soluzione più ovvia. Sono io? Ho letto dozzine di thread e non ho trovato una soluzione a questo problema che funzioni nel mio caso d'uso, né ho visto un'elaborazione del problema esatto di divisione e ri-unione di stream (anche se non posso essere il primo uno per affrontare questo). Dovrei usare solo pipe con nome? Ho provato ma ho avuto difficoltà a farlo funzionare, quindi forse questa è un'altra storia per un'altra discussione. Sto usando bash in RHEL5.8.
Sembra che la tua domanda abbia una soluzione _che funziona_ - quindi stai chiedendo una soluzione diversa? In genere quel tipo di suddivisione non appare frequentemente negli script di shell, ma lo fa spesso in strumenti specializzati come Hadoop-MapReduce - Non credo che troveremo qualcosa di meglio come pipeline bash. – Soren
@ Soren - sì, mi chiedo se c'è una soluzione migliore. Non sto perdendo il sonno perché la mia soluzione sembra funzionare, ma mi aspetto che ci sia una soluzione che non implichi il reindirizzamento dello stdout a/dev/null e sono curioso di sapere dove ho sbagliato perché potrebbe essere informativo per me (o altri) mentre continuo a svilupparmi. –