一、標(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流:stdinstdoutstderr
三個(gè)stream對(duì)應(yīng)的文件描述符分別為:012
二、管道符
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:~$