2013-06-24 146 views
8

這只是一個假設性問題 - 沒有解決任何實際問題 - 只能學習bash。粘貼tee命令的結果

隨着tee命令是可能的分割輸出到多個不同的數據流,如:

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

所以圖形完成下一

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

現在,隨着paste命令可以例如

paste file1 file2 | command3 

而我又可以從不同的程序重定向到粘貼輸出,如:

paste <(ls) <(ls) | command3 

的問題是:有可能在兩股稍微加入到一個,像

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

Ps:表示沒有中間文件...

+5

不是沒有中間文件或命名管道。請參閱'mkfifo' – SheetJS

+3

這是一個我喜歡看到的問題 - 有些什麼不是微不足道的。不幸的是,我不知道bash足夠深入地展示如何通過@Nirk建議的「命名管道」實現此目標... +1 – kobame

回答

3

下面介紹如何使用命名爲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 

工作實施例:

$ 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

我沒有寫它,@JonathanLeffler補充說(在添加工作示例之前) 。 – Barmar

+0

@ l0b0:陷阱中的「退出1」表示過程失敗; '退出0'會給人以錯誤的印象,認爲這個過程是成功的。如果不添加'exit'就意味着'以最後一個命令的狀態退出,這將是'rm -f',這將成功,所以退出狀態將爲0.'陷阱'可以確保臨時FIFO在外殼能夠移除它們時被移除。如果你用'kill -9'殺死這個進程,那麼它就沒有辦法清理。但是如果使用HUP,INT,QUIT,PIPE或TERM(1,2,3,13,15),那麼在退出之前,外殼將自行清理。 –

+0

@JonathanLeffler令人困惑的是,您在陷阱信號列表中加入了'0',這意味着它會在正常退出期間運行並將其變爲失敗退出。但實際上不會發生這種情況,因爲您在最後以'trap 0'退出時禁用了陷阱,所以原始陷阱命令中沒有這一點。 – Barmar