Linux 標(biāo)準(zhǔn)輸入輸出、管道符、重定向

一、標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤

對(duì)于 Linux 內(nèi)核中的標(biāo)準(zhǔn) I/O 庫,stdio 提供了一個(gè)高效的緩存 I/O 流接口。一般情況下,每個(gè)程序在啟動(dòng)時(shí)都會(huì)有三個(gè) stream(流)被預(yù)定義,一個(gè)用于輸入,一個(gè)用于輸出,還有一個(gè)用于打印診斷或者錯(cuò)誤信息。對(duì)于 Linux 系統(tǒng)來說,讀取標(biāo)準(zhǔn)輸入和打印標(biāo)準(zhǔn)輸出的地方默認(rèn)情況下都是當(dāng)前所使用的終端。

對(duì)應(yīng) shell 中常使用的三種標(biāo)準(zhǔn) I/O 流:stdin stdout stderr
三個(gè) stream 對(duì)應(yīng)的文件描述符分別為:0 1 2

二、管道符

Linux 管道可以用于 Linux 程序之間,Linux 命令之間以及 Linux 程序和命令之間的通信。在 shell 中,管道符(pipeline)shell 編程中眾多控制操作符里的一個(gè),用來分隔一個(gè)或多個(gè)命令的序列。shell 編程中管道符號(hào)是豎杠符號(hào) |(有時(shí)會(huì)用到 |& 符號(hào)),在 shell 中使用管道的格式如下,代表著 command1 的標(biāo)準(zhǔn)輸出作為 command2 的標(biāo)準(zhǔn)輸入使用,而 command2 的標(biāo)準(zhǔn)輸出又作為 command3 的標(biāo)準(zhǔn)輸入使用:

command1 | command2 | command3

三、重定向

命令 說明
command > file 將輸出重定向到 file(把命令輸出存入文件
command < file 將輸入重定向到 file(把文件內(nèi)容作為命令輸入
command >> file 將輸出以追加的方式重定向到 file
n> file 將文件描述符為 n 的內(nèi)容重定向到 file(存入文件
n>> file 將文件描述符為 n 的文件以追加的方式重定向到 file
2>&1 將標(biāo)準(zhǔn)錯(cuò)誤重定向到標(biāo)準(zhǔn)輸出
1>&2 將標(biāo)準(zhǔn)輸出重定向到標(biāo)準(zhǔn)錯(cuò)誤

* 注意命令中的空格

一些例子

1、< 將后面的文件中的內(nèi)容作為輸入交給前頭的命令來處理。這就是所謂的 “將輸入重定向到文件”,文件內(nèi)容為輸入內(nèi)容:

mcdx@ubuntu:~$ wc .vimrc
 16  61 799 .vimrc
mcdx@ubuntu:~$ wc < .vimrc  # 注意這兩個(gè)命令的打印結(jié)果的區(qū)別
 16  61 799

2、| 管道把標(biāo)準(zhǔn)輸出傳給后面的命令來處理,> 又把 cat 命令的標(biāo)準(zhǔn)輸出放入后面的文件里了:

mcdx@ubuntu:~$ echo 'hello world' | cat > a
mcdx@ubuntu:~$ cat a
hello world

3、<a 文件的內(nèi)容作為 cat 要處理的數(shù)據(jù)即 cat 的標(biāo)準(zhǔn)輸入,> 把前面的 cat 命令的標(biāo)準(zhǔn)輸出放到后面的 b 文件中:

mcdx@ubuntu:~$ cat > b < a  # 等同于 cat < a > b
mcdx@ubuntu:~$ cat b
hello world

4、對(duì)比“例 2”,|& 把標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤都傳入后面的命令來處理:

mcdx@ubuntu:~$ cat a 晴空一鶴排云上
hello world
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄
mcdx@ubuntu:~$ cat a 晴空一鶴排云上 |& cat
hello world
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄
mcdx@ubuntu:~$ cat a 晴空一鶴排云上 |& cat > c
mcdx@ubuntu:~$ cat c
hello world
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄

5、2> 將標(biāo)準(zhǔn)錯(cuò)誤傳入后面的文件,對(duì)比“例 4”,注意區(qū)別:

mcdx@ubuntu:~$ cat a 晴空一鶴排云上 2> c
hello world
mcdx@ubuntu:~$ cat c
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄

6、如果想把標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤分別放倆文件中,可以這樣:

mcdx@ubuntu:~$ cat a 晴空一鶴排云上 > d 2> f
mcdx@ubuntu:~$ cat d
hello world
mcdx@ubuntu:~$ cat f
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄

7、關(guān)于 2>&1 1>&2 &> :> 的用法:

# 將 cat 命令的標(biāo)準(zhǔn)輸出重定向到 err 文件,標(biāo)準(zhǔn)錯(cuò)誤保持不變,默認(rèn)打印到終端
mcdx@ubuntu:~$ cat a 晴空一鶴排云上 > err
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄
mcdx@ubuntu:~$ cat err
hello world

# 首先將 cat 命令的標(biāo)準(zhǔn)輸出重定向到文件,然后將標(biāo)準(zhǔn)錯(cuò)誤重定向?yàn)闃?biāo)準(zhǔn)輸出
# 此時(shí)標(biāo)準(zhǔn)輸出去哪里,標(biāo)準(zhǔn)錯(cuò)誤就去哪里
# 本來兩者都應(yīng)該打印到終端,現(xiàn)在都定向到了文件
mcdx@ubuntu:~$ cat a 晴空一鶴排云上 > err 2>&1 
mcdx@ubuntu:~$ cat err
hello world
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄

# 首先將 cat 命令的標(biāo)準(zhǔn)錯(cuò)誤重定向到標(biāo)準(zhǔn)輸出,此時(shí)兩者都應(yīng)該打印到終端
# 這就相當(dāng)于 2>&1 沒起作用,因?yàn)闃?biāo)準(zhǔn)錯(cuò)誤跟隨標(biāo)準(zhǔn)輸出,但標(biāo)準(zhǔn)輸出沒動(dòng)
# 然后標(biāo)準(zhǔn)輸出被重定向到 err 文件,標(biāo)準(zhǔn)錯(cuò)誤被留在了終端
mcdx@ubuntu:~$ cat a 晴空一鶴排云上 2>&1 > err
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄
mcdx@ubuntu:~$ cat err
hello world
# 同理,1>&2 將標(biāo)準(zhǔn)輸出重定向到標(biāo)準(zhǔn)錯(cuò)誤,結(jié)果一樣
mcdx@ubuntu:~$ cat a 晴空一鶴排云上 2> err 1>&2
mcdx@ubuntu:~$ cat err 
hello world
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄

# 將 cat 命令的標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤分別都重定向到 err 文件
mcdx@ubuntu:~$ cat a 晴空一鶴排云上 &> err 
mcdx@ubuntu:~$ cat err 
hello world
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄

# :> 清空文件內(nèi)容
mcdx@ubuntu:~$ cat err 
hello world
cat: 晴空一鶴排云上: 沒有那個(gè)文件或目錄
mcdx@ubuntu:~$ :> err 
mcdx@ubuntu:~$ cat err 
mcdx@ubuntu:~$ 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容