1. 程式人生 > >linux-流操作

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是約定的結束標記,在命令最初必須指定結束標記,當輸入該標記時,視作輸入完畢。

結束標記常用ENDEOF進行表示。

雙向

  • 直接輸入到文字
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,命令關聯流。

管道teeinput --> cat --> tee --> godme.filecat --> tee,流關聯命令。

  • 多方向

這個差別需要看現實結果

重定向文字有結果,但是控制檯無輸出。

tee兩者都會有結果。

這算是最明顯的關係了。

管道實現了關聯,單卻只能單連線,tee可以關聯到多個輸入。

  • tee

tee實現的更多是分流

首先,是多條流。

cat << EOF | tee godme.txt judas.txt foreva.txt

它能夠直接連線多個檔案進行輸出。

然後必須理解的更關鍵的是擷取複製

ls -lhi | tee files.txt | wc -l

它的確能夠輸出到多個,但是,實際上它只是額外複製流指向指定的檔案。

原本的流,依舊是存在的,沒有截斷,沒有重定向,僅僅是重定向了複製的流,有多個流向時依然。

所謂的分流是在複製之後,小細節。

小結

所謂的程式到程式,依然是建立在輸出到輸入的關聯之上。

前面為了理解有所省略,但是一定要區分開來。