[Linux]基本I/O重定向


在我們設置定時任務的時候經常會使用標准輸出和標准錯誤輸出。這個在Linux是一個非常重要的概念,而且這個很有用。程序應該有數據庫的來源端、數據的目的端,以及報告問題的地方,它們被稱為標准輸入、標准輸出以及標准錯誤輸出。

 
程序啟動的時候,默認情況下,標准輸出、輸入都會已經打開,且已准備好供其使用。我們使用Xshell連接並登陸上服務器的時候,默認下終端就是標准輸入、輸出端。可以試試cat命令。
$ cat                                  #未指定任何的參數是,讀取默認的標准輸入、寫入到默認的標准輸出
建華是可以玩耍的小伙伴                    #用戶輸入(此時終端默認是標准輸入)
建華是可以玩耍的小伙伴                    #程序將內容輸出到標准輸出(此時終端默認為標准輸出)
^D                                     #輸入Ctrl-D 告訴程序文件結尾

 

重定向與管道
Shell提供了數種語法,可以修改默認的IO的來源端和目的端,就是標准輸入和輸出的地方。
< 修改標准輸入 sort < ucid.txt 默認下,標准輸入為終端,此時可以更改為你想要的地方
<<   Command << delimiter 從標准輸入中讀入,直到遇到delimiter分割符
> 修改標准輸出 ls -l > listinfo.txt 默認下,標准輸出為終端,此時可以修改默認輸出的地方。譬如可以將標准輸出的內容寫在文件中。
如果文件已存在,會被覆蓋掉。
>>  輸出附件到文件 ls -l >> listinfo.txt 與[>]不一樣的是,[>]會清空原來的內容,而[>>]只是將標准輸出追加到文件結尾處。
| 建立管道 program1 | program2 1. program1的標准輸出為program2的標准輸入;
2. 管道的執行效率比使用臨時文件的程序起碼高一個數量級;
 
[<]例子
場景:對文件內容的信息進行排序
[nemo@name tool]$ cat show.txt
7291418
2233803
8031001
1258962
[weiyg@name tool]$ sort < show.txt
1258962
2233803
7291418
8031001

 

[>]例子
場景:打印內容到文件
[weiyg@name script]$ ll
total 20
-rw-rw-r--. 1 weiyg weiyg 254 Dec 31 13:45 ssh.rb
-rw-r--r--. 1 weiyg weiyg 476 Dec 30 11:48 sshx.rb
-rw-rw-r--. 1 weiyg weiyg  12 Dec 26 16:57 test.rb
[weiyg@name script]$ ls -l > listinfo.txt
[weiyg@name script]$ cat listinfo.txt 
total 20
-rw-rw-r--. 1 weiyg weiyg   0 Jan 22 21:35 listinfo.txt
-rw-rw-r--. 1 weiyg weiyg 254 Dec 31 13:45 ssh.rb
-rw-r--r--. 1 weiyg weiyg 476 Dec 30 11:48 sshx.rb
-rw-rw-r--. 1 weiyg weiyg  12 Dec 26 16:57 test.rb
在定時任務上面經常使用。因為定時任務執行的內容,不會打印到終端。如果需要查看結果的話就很麻煩。而打印到文件中的話,隨時都可以查看了。不過這里往往用[>>]追加比較多。
 
[>>]例子
沒啥好說的,跟[>]就是一個[>]會覆蓋原有的文件,而[>>]只是追加。
 
[|]管道例子
場景:查詢id為19217xxxx的玩家在1月15日使用道具的日志
[weiyg@name flash]$ bzcat *useprop.log.2014-01-15.bz2 |grep '19217xxxx'
1389717003317|19217xxxx|2|304|305|0|
1389717005097|19217xxxx|2|303|304|0|

這是查詢游戲日志的一個例子。默認下,系統會將游戲5天前的日志進行打包壓縮。而此時需要查詢5天前的日志的話,使用上面的方法無論在效率上還是方便上,管道都有使用臨時文件無法比擬的又是。當然使用下面的方法:

[weiyg@name flash]$ bzcat *useprop.log.2014-01-15.bz2 > tem.log
[weiyg@name flash]$ grep '19217xxxx' tem.log
1389717003317|19217xxxx|2|304|305|0|
1389717005097|19217xxxx|2|303|304|0|
也可以達到相同的結果,但相比使用管道,一、需要使用臨時文件,讀寫在磁盤需要時間;二、臨時文件還需要手動刪除,比較麻煩。
注:bzcat 可以直接顯示壓縮文件的內容
 
特殊文件:/dev/null 與/dev/tty
/dev/null  傳送到此文件的數據都會被系統丟掉,,就是輸出到一個空設備的意思。
/dev/tty   程序打開此文件時,Linux會自動將它重定向到一個終端。
 
文件描述符
在定時任務,我們經常在重定向的時候,喜歡這樣操作。
33 1 * * * /home/weiyg/crontab/clear_logs.sh > /dev/null 2>&1
后面的 2>&1是什么意思呢,這里就要理解文件描述符和綁定重定向的概念了。
文件 文件描述符
輸入文件——標准輸入 0(默認為終端(網上有說默認為鍵盤的))
輸出文件——標准輸出 1(默認為終端)
錯誤輸出文件——標准錯誤 2(默認為終端)
綁定重定向
Commond >&m 標准輸出重定向到文件描述符m中
Command <&- 關閉標准輸入
Command 0>&- 關閉標准輸出
 
此時我們再去理解[2>&1],就容易多了。[2]是標准錯誤的文件描述符,而[>&1]的意思重定向到標准輸出。那么定時任務的解釋就是,將[clear_logs.sh]執行的標准輸出和標准錯誤重定向到[/dev/null](就是丟掉輸出的內容)。
我是這樣理解(不一定正確)上面的定時任務的(分2部分):
clear_logs.sh > /dev/null     #將clear_logs.sh執行的標准輸出輸出到/dev/null
clear_logs.sh 2> /dev/null    #將clear_logs.sh執行的標准錯誤輸出到/dev/null,只是clear_logs.sh不是執行了2次,只是1次。這里的&1代表的就是/dev/null

 

 //-----------------------
以上為本次學習I/O重定向的筆記。

參考資料:1. 《Shell腳本學習指南》 Arnold Robbins & Nelson H.F. Beebe著 機械工業出版社
              2. 《Linux shell的標准輸入、輸出和錯誤 》 http://blog.csdn.net/cjfeii/article/details/10084343

共勉之


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM