linux-流操作
流型別
型別 | 編號 | 說明 |
---|---|---|
stdin |
0 |
標準輸入 |
stdout |
1 |
標準輸出 |
stderr |
2 |
標準錯誤 |
重定向
符號 | 作用 | 效果 |
---|---|---|
> |
輸出重定向 | 覆蓋 |
>> |
輸出重定向 | 追加 |
< |
輸入重定向 | 輸入 |
輸出重定向
- 限定
# 基本資料填充 echo "old content" > /tmp/out.log # 重定向輸出 echo "output redirect test" > /tmp/out.log # 追加重定向 echo "append content" >> /tmp/out.log
>
會直接覆蓋檔案內容,>>
會進行追加。
>
對於檔案影響較大,不建議使用,同時可以新增額外限定。set -C
set -C
會取消>
的覆蓋功能,當檔案不存在的時候沒有任何問題。如果檔案存在的話就會報錯。
如果需要可覆蓋的話可以
set +C
。
- 型別
# 顯示結果並重定向到指定檔案 ls /var > /tmp/out.txt # ..... ls /varr > /tmp/out.txt
第一條指令會正常執行,而第二條指令會進行報錯。
這是因為
/varr
這個資料夾不存在。具體的原因是
>
重定向預設操作的是stdout
,當報錯的時候,操作物件換成了stderr
。型別不匹配,於是錯誤資訊直接輸出到控制檯,沒有直接輸出到檔案。
想要儲存錯誤資訊的話
ls /varr 2> /tmp/out.txt
通過
2
指定操作流為stdout
,即重定向錯誤輸出
。這樣就會把錯誤資訊給重定向輸出到指定檔案。但是,此時
/varr
替換成/var
,資訊就會直接顯示,因為沒有錯誤
。ls /var > /tmp/out.txt 2> /tmp/err.txt
採取
雙重重定向
,相當於對每個流
進行了指定,存在的話就進行操作。還能夠對不同的資訊進行歸類。
- 二合一
ls /var > /tmp/log.txt 2> /tmp/log.txt
兩者指向同一個檔案即可,不過還可以更方便一些。
ls /varr &> /tmp/log.txt
&
就能夠自動整合兩個流重定向到同一個檔案。但是,只能
&>
,卻沒有&>>
。
輸入重定向
- 簡單輸入流
cat < /etc/passwd
重定向輸入流
cat /etc/passwd
:讀取檔案並輸出
cat < /etc/passwd
:讀取流並輸出
- 文件輸入流
echo << EOF > first > second > third > EOF
上面的
>
不在命令範圍內,enter
就會自動換行並顯示。當我們需要格式換行的時候,通過
<<
就可以進行多行的直接輸入,而不是\n
。類似於
python
的三引號,能夠自動識別格式。
EOF
是約定的結束標記,在命令最初必須指定結束標記,當輸入該標記時,視作輸入完畢。結束標記常用
END
或EOF
進行表示。
雙向
- 直接輸入到文字
cat >> godme.txt << EOF > first > second > third > EOF
螢幕輸入,但是沒有輸出。
檢視文字,全部進去了
管道
把前一個的輸出連線作為後一個的輸入,是謂管道。
- 只顯示資料夾
ls -lhi | grep "^d"
- 檔名全大寫
ll | tr 'a-z' 'A-Z'
雙端
- 流方向
cat >> file << EOF
- 管道流向
- 流控制
重定向
並非是流控制
的手段。它只是改變了
流向
,更主要的是它的核心是操作
,所謂流不過是兩端
的被隔絕的產物。我們總是通過
命令
才能把所謂的輸入
同輸出
關聯起來。
cat >> godme.file << EOF
每次,都必須得有這麼一個關聯命令,不做額外操作的時候,僅僅
cat
,實在不便。
ls -lhi | grep "^-" | tr 'a-z' 'A-z'
如果說
重定向
通過命令連線了流
。那
管道
就是通過流
關聯了命令。更多的場景下,我們更加關注的是命令的連線而不是流的連線。
管道
自動連線了流
,讓操作更加方便。
- 差異
實體 | 作用 | 範圍 |
---|---|---|
流 | I/O |
終端 |
管道 | O2I |
過程 |
- 差異
所謂流,描述的只是
程式(命令)
的元素
和結果
,通過程式
才有了一絲關聯。所謂
管道
,也不具有實際含義,只是把結果
轉接作為了元素
。流只關心
來源
和去處
,因此,它註定只能在兩端具有用途。
管道
不關心來源
,也不關心去處
,它的核心作用是連線
,所以更多的使用在過程
當中。
- 同源
流
只是抽象的東西,更多的差異來源於操作,根源部分任然是同樣的。
重定向
,讓我們看到的是直接的流操作,注重流
的方向性和獨立性。
管道連線
,遮蔽了重定向
和流對接
,更偏向於流的順序性和相關性。不可把
操作
的差異理解為流
,這樣會誤入歧途。同時,區分、理解操作引起的差異,能夠對流進行深入的理解。
- 漸進
- 重定向
重定向,讓我們初步認識了流,並瞭解了基本概念。
- 管道
管道更深入一層,實現了
流管理
,讓零散的獨立的IO
連貫為O2I
。把
程式
弱化,把流程
曝光,把目光轉移到更實用的地方。
tee
不過管道有一個小侷限----單向輸出。
管道實現了
對接
,不過還是留下了單向
的毛病。不過
tee
彌補了這個不足。# 重定向 cat >> godme.file << EOF # 管道tee cat << EOF | tee godme.txt
其中最關鍵的在於兩點
- 流向
重定向
:input
-->cat
-->godme.file
,命令關聯流。
管道tee
:input
-->cat
-->tee
-->godme.file
,cat --> tee
,流關聯命令。
- 多方向
這個差別需要看現實結果
重定向
文字有結果,但是控制檯無輸出。
tee
兩者都會有結果。這算是最明顯的關係了。
管道實現了關聯,單卻只能單連線,
tee
可以關聯到多個輸入。
- tee
tee
實現的更多是分流
。首先,是多條流。
cat << EOF | tee godme.txt judas.txt foreva.txt
它能夠直接連線多個檔案進行輸出。
然後必須理解的更關鍵的是
擷取複製
ls -lhi | tee files.txt | wc -l
它的確能夠輸出到多個,但是,實際上它只是額外複製流指向指定的檔案。
原本的流,依舊是存在的,沒有截斷,沒有重定向,僅僅是重定向了複製的流,有多個流向時依然。
所謂的
分流
是在複製
之後,小細節。
小結
所謂的
程式到程式
,依然是建立在輸出到輸入
的關聯之上。前面為了理解有所省略,但是一定要區分開來。