2013-06-24 17 views
8

Questa è solo una domanda ipotetica - non risolvere alcun problema reale - solo apprendimento bash.Incollare il risultato del comando tee

Con il comando tee è possibile dividere l'uscita a più differenti flussi, come:

command1 | tee >(commandA1 | commandA2 >file1) >(commandB1 | commandB2 >file2) >file0 

così graficamente avviene la successiva

    ---commandA1---commandA2--> file1 
       /
command1---tee-------> file0 
       \ 
        ---commandB1---commandB2--> file2 

Ora, con il comando paste può ad esempio

paste file1 file2 | command3 

ma ancora una volta posso reindirizzare l'output incolla da un diversi programmi, come:

paste <(ls) <(ls) | command3 

La domanda è: è possibile in qualche modo unire i due flussi in un unico, qualcosa di simile a

    ---commandA1---commandA2--- 
       /       \ 
command1---tee-------> file0     --- paste---command3 
       \       /
        ---commandB1---commandB2--- 

Ps: medio senza file intermedi ...

+5

Non senza un file intermedio o named pipe. Vedi 'mkfifo' – SheetJS

+3

Questa è una sorta di domande che amo vedere - in qualche modo, ciò che non è banale. Sfortunatamente, non so bash abbastanza profondamente per mostrare come ottenere questo risultato con "named pipe" come suggerito da @Nirk ... +1 – kobame

risposta

3

Ecco come farlo con p IPES:

trap "rm -f /tmp/file1 /tmp/file2; exit 1" 0 1 2 3 13 15 
mkfifo /tmp/file1 
mkfifo /tmp/file2 
command1 | tee >(commandA1 | commandA2 >/tmp/file1) >(commandB1 | commandB2 >/tmp/file2) >file0 
paste /tmp/file1 /tmp/file2 | command3 
rm -f /tmp/file1 /tmp/file2 
trap 0 

esempio funzionante:

$ cd -- "$(mktemp -d)" 
$ trap "rm -f pipe1 pipe2; exit 1" 0 1 2 3 13 15 
$ mkfifo pipe1 pipe2 
$ printf '%s\n' 'line 1' 'line 2' 'line 3' 'line 4' | tee \ 
>(sed 's/line /l/' | head -n 2 > pipe1) \ 
>(sed 's/line /Line #/' | tail -n 2 > pipe2) \ 
> original.txt 
$ paste pipe1 pipe2 | sed 's/\t/ --- /' 
l1 --- Line #3 
l2 --- Line #4 
$ rm pipe1 pipe2 
$ trap 0 
+0

Non l'ho scritto, @JonathanLeffler ha aggiunto che (prima di aggiungere l'esempio di lavoro) . – Barmar

+0

@ l0b0: 'exit 1' nella trap per indicare che il processo ha avuto esito negativo; 'exit 0' darebbe l'impressione fuorviante che il processo abbia avuto successo. E non aggiungere 'exit' significherebbe 'uscire con lo stato dell'ultimo comando, che sarebbe 'rm -f', che avrebbe avuto successo, quindi lo stato di uscita sarebbe 0. Il' trap' si assicura che i FIFO temporanei vengono rimossi quando la shell è in grado di rimuoverli. Se uccidi il processo con 'kill -9', non c'è nulla che possa fare per pulire. Ma se usi HUP, INT, QUIT, PIPE o TERM (1, 2, 3, 13, 15), la shell si pulirà da sola prima di uscire. –

+0

@JonathanLeffler La confusione è che includi '0' nell'elenco dei segnali che intrappoli, il che significa che verrà eseguito durante l'uscita normale e trasformato in un'uscita in errore. Ma in realtà non succederà perché disabiliti il ​​trap in uscita con 'trap 0' alla fine, quindi non c'è alcun punto nel comando trap originale. – Barmar

Problemi correlati