首先說一下什么是數據流重定向,所謂數據流重定向簡單來說就是一個過程,這個過程捕捉一個文件,或者命令,程序,腳本,甚至腳本中的代碼塊(code block)的輸出,然后把捕捉到的輸出,作為輸入發送給另外一個文件,命令,程序,或者腳本。
談到數據流重定向,我們首先需要了解文件描述符的概念。對於linux內核而言,所有打開的文件都通過文件描述符引用。文件描述符是一個非負整數。當打開一個現有文件或創建一個新文件時,內核向進程等返回一個文件描述符。按照慣例,unix系統shell把文件描述符0與進程的標准輸入關聯,文件描述符1與標准輸出關聯,文件描述符2與標准錯誤關聯。總結如下:
標准輸入:文件描述符0,通常指鍵盤的輸入 。使用符號<或<<
標准輸出:文件描述符1,通常指命令執行所回傳的正確信息 ,默認輸出到屏幕u。使用符號>或>>
標准錯誤:文件描述符2,通常指命令執行失敗后,所回傳的信息,也是默認輸出到屏幕。試用符號2>或2>>
默認情況下>和>>分別表示1>或1>>,<和<<與0<和0<<等價。
標准輸出重定向:
#ls
表示列出當前目錄條目,並將結果輸出到屏幕。
#ls 1>file1
以上命令會把命令的標准輸出重新定向到一個文件file,而不是顯示到屏幕上,如果不指明文件標識符,系統默認的就是1, 因此1可以省略。
即這個命令等同於
#ls >file1
如果file1不存在,則系統會自動創建。如果已經存在,那么系統首先會把這個文件清空,然后再將數據寫入該文件。也就是說>輸出到一個已存在的文件,那么會覆蓋這個文件。如果不想覆蓋,可以使用>>。表示將重定向數據追加到file1文件的末尾。
標准錯誤重定向:
#ls -qw 2>errorfile
表示將錯誤信息不輸出到屏幕,而是寫入errorfile。注意這里的2不能省略。因為>與1>等同,默認是標准輸出重定向。所以這里要寫成2>,表示標准錯誤重定向。-qw用來產生錯誤信息。
把標准錯誤和標准輸出寫入同一個文件:
#./a.out &>outfile
這個命令把./a.out的標准輸出和標准錯誤重定向到outfile。&在這里表示標准錯誤和標准輸出。下面是另一種寫法:
#./a.out > outfile 2>&1
下面是一個錯誤的例子:
#./a.out > outfile 2>outfile
標准輸入重定向:
#grep search-world <filename 或 grep search-world 0<filename
還有下面這種方式:
cat > catfile < ~/.bashrc
它代表將~/.bashrc的內容作為輸入,然后將這些內容寫入catfile
關閉文件:
"&-"表示關閉文件標識符
有關關閉文件標識符的操作請參考下面
n<&- 關閉輸入文件標識符n 0<&-或<&- 關閉標准輸入stdin n>&- 關閉輸出文件標識符n 1>&-或>&-關閉標准輸出stdout
屏蔽標准輸出或標准錯誤:
./a.out > /dev/null #等同於./a.out 1>dev/null 表示屏蔽標准輸出
./a.out 2>/dev/null #表示屏蔽標准錯誤
./a.out > /dev/null 2>/dev/null #表示同時屏蔽標准輸出和標准錯誤
打開文件:
#exec 3<>filename 把文件filename打開,並指定文件標識符為3
命令j<>filename表示把文件打開,並指明文件標識符為j
我們什么時候需要重定向:
1.屏幕輸出的信息很重要,而且我們需要將它存下來的時候。
2. 后台執行中的程序,不希望它干擾屏幕正常的輸出結果時。
3. 一些系統的例行命令。(例如寫在/etc/crontab中的文件)的執行結果時,希望它可以存下來。
4. 一些執行命令的可能已知錯誤信息時,想以“2>dev/null"將它丟掉
5. 錯誤信息與正確信息需要分別輸出時
常用重定向命令:
cmd > file 把 stdout 重定向到 file 文件中;
cmd >> file 把 stdout 重定向到 file 文件中(追加);
cmd 1> fiel 把 stdout 重定向到 file 文件中;
cmd > file 2>&1 把 stdout 和 stderr 一起重定向到 file 文件中;
cmd 2> file 把 stderr 重定向到 file 文件中;
cmd 2>> file 把 stderr 重定向到 file 文件中(追加);
cmd >> file 2>&1 把 stderr 和 stderr 一起重定向到 file 文件中(追加);
cmd < file >file2 cmd 命令以 file 文件作為 stdin,以 file2 文件作為 stdout;
cat <>file 以讀寫的方式打開 file;
cmd < file cmd 命令以 file 文件作為 stdin;
cmd << delimiter Here document,從 stdin 中讀入,直至遇到 delimiter 分界符。
>&n 使用系統調用 dup (2) 復制文件描述符 n 並把結果用作標准輸出;
<&n 標准輸入復制自文件描述符 n;
<&- 關閉標准輸入(鍵盤);
>&- 關閉標准輸出;
n<&- 表示將 n 號輸入關閉;
n>&- 表示將 n 號輸出關閉;
與重定向相關的題目:
此題來自《unix環境高級編程》(第3版)P73 3.5
在Bourne shell、Bourne-again shell 和Korn shell中,digit1>&digit2表示將描述符digit1的重定向至描述符digit2的同一文件。請說明下面兩條命令的區別。
./a.out > outfile 2>&1
./a.out 2>&1 >outfile
答:因為shell從左到右處理命令行,所以:
./a.out > outfile 2>&1 等同於./a.out 1>outfile 2>&1
首先執行 >outfile 設置標准輸出到outfile,然后執行2>&1,即調用dup將標准輸出復制到描述符2(標准錯誤上),其結果是將標准輸出和標准錯誤設置為同一個文件,即描述符1和2指向同一個文件表項。而對於命令行
./a.out 2>&1 >outfile
首先執行dup,所以描述符2成為終端(假設命令是交互執行的),標准輸出重定向到outfile。結果是描述符1指向outfile的文件表項,描述符2指向終端的文件表項。
參考資料:
1.http://os.51cto.com/art/201003/187688.htm
2.http://blog.csdn.net/ljianhui/article/details/9262737
3.https://www.ibm.com/developerworks/cn/linux/l-iotips/
4.《unix環境高級編程》
命令j<>filename表示把文件打開,並指明文件標識符為j