tee [options] FILE1 FILE2 FILE3...
tee的做用是將一份標準輸入多重定向,一份重定向到標準輸出/dev/stdout,而後還將標準輸入重定向到每一個文件FILE中。shell
例如:bash
$ cat alpha.log | tee file1 file2 file3 | cat $ cat alpha.log | tee file1 file2 file3 >/dev/null
上面第一個命令將alpha.log的文件內容重定向給file{1..3}和標準輸出經過管道傳遞給cat;
上面第二個命令將alpha.log的文件內容重定向給file{1..3}和/dev/null。工具
寫多了腳本的人可能遇到過這樣一種需求:將一份標準輸入,重定向到多個命令中去。大概是這樣的:命令行
| CMD1 ↗ INPUT | tee ↘ | CMD2
其實bash自身的特性就能實現這樣的需求,經過重定向到子shell中,就能模擬一個文件重定向行爲:code
cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c")
(實際上這裏的兩個>(cmd_list)
不是重定向,而是進程替換。命令行解析開始時,將首先進行進程替換,這兩個grep將等待標準輸入。而後啓動cat和tee,而後tee將標準輸出交給兩個進程的標準輸入)進程
上面的命令將alpha.txt文件內容重定向爲3份:一份給第一個grep命令,一份給第二個grep命令,一份給標準輸出。假如alpha.txt的內容是a b c d e
5個字母分別佔用5行(每行一個字母),上面的輸出結果以下:cmd
a b c d e # 前5行是重定向到/dev/stdout的 a b # 這2行是重定向給第一個grep後的執行結果 b c d # 這3行是重定向給第二個grep後的執行結果
若是不想要給標準輸出的那份重定向,加上>/dev/null
:io
cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c") >/dev/null
可是必須注意,tee將數據重定向給不一樣命令時,這些命令是獨立執行的,它們都會各自打開一個屬於本身的STDOUT,若是它們都重定向到標準輸出,因爲涉及到多個不一樣的/dev/stdout,它們的結果將出現兩個問題:file
例如:語法
$ cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c") >/dev/null $ a # 結果直接出如今提示符所在行 b b c d $ cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c") >/dev/null b c # 此次的結果和上次的順序不同 d a b
這兩個問題,在寫腳本過程當中必須解決。
對於第二個問題:不一樣/dev/stdout同時輸出時在屏幕上交叉輸出的問題,只需將它們再次重定向走便可,這樣兩份不一樣的/dev/stdout都再次同時做爲一份標準輸入:
$ cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c") >/dev/null | cat
對於第一個問題:不一樣/dev/stdout同時輸出時,輸出順序的隨機性,這個沒有好方法,只能在各命令行中將各自的結果保存到文件中:
$ cat alpha.txt | tee >(grep -E "a|b" >file1) >(grep -E "d|b|c" >file2) >/dev/null
因此,tee在重定向到多個命令中是有缺陷的,或者說用起來很是不方便,只要將各命令的結果各自保存時,才能一切按照本身的預期進行。那麼,pee登場了,多重定向很是好用的一個命令。
pee是moreutils包中的一個小工具,先安裝它(epel源中有):
yum -y install moreutils
在man pee中,pee的做用是將標準輸入tee給管道。語法:
pee ["cmds"]
不是很好理解,能夠經過幾個示例直接感覺它的用法。
$ cat alpha.txt | pee 'grep -E "a|b"' 'grep -E "d|b|c"' a b b c d
因此,它的基本用法是pee "CMD1" "CMD2"
。
若是想將結果保存到文件,只需加一個命令便可,例以下面的cat >myfile
。
$ cat alpha.txt | pee 'grep -E "a|b"' 'grep -E "d|b|c"' 'cat >myfile'
和tee有一樣的問題,若是各命令都沒有指定本身的標準輸出重定向,它們將各自打開一個屬於本身的/dev/stdout,一樣會有多個/dev/stdout同時輸出時結果數據順序隨機性的問題,可是不會有多個/dev/stdout同時輸出時交互式的隔斷性問題,由於pee會收集各個命令的標準輸出,而後將收集的結果做爲本身的標準輸出。
pee和tee最大的不一樣,在於pee未來自多個不一樣命令的結果做爲pee本身的標準輸出,因此下面的命令是能夠像普通命令同樣進行重定向的。
INPUT | pee CMD1 CMD2 >/FILE
而tee則不一樣,是將cmd1和cmd2的結果放進標準輸出(假設各命令自身沒有使用重定向),保存到FILE中的是tee讀取的標準輸入。
INPUT | tee >(cmd1) >(cmd2) >/FILE
因此,想要重定向tee中cmd1和cmd2的總結果,必須使用額外的管道,或者將整個tee放進子shell。
INPUT | tee >(cmd1) >(cmd2) >/dev/null | cat >FILE1 INPUT | ( tee >(cmd1) >(cmd2) >/dev/null ) >/FILE1