本篇是Linux小白最佳實踐第5篇,目的就是讓白菜們瞭解Linux進程之間是如何對話的。以前連載的幾篇,在微信上引發了不少的反響,有人也反映圖多文字少,感受沒有乾貨.本篇選了大部分是實戰講解的"管道與重定向"進行連載,但願讓讀者能真正學到東西.segmentfault
8.3管道與重定向微信
管道與重定向是Linux系統進程間的一種通信方式,在系統管理中有着舉足輕重的做用。絕大部分Linux進程運行時須要使用3個文件描述符:標準輸入、標準輸出和標準錯誤輸出,對應的序號是0、1和2。通常來講,這3個描述符與該進程啓動的終端相關聯,其中輸入通常爲鍵盤。重定向和管道的目的是重定向這些描述符。管道通常爲輸入和輸出重定向的結合,一個進程向管道的一端發送數據,而另外一個進程從該管道的另外一端讀取數據。管道符是「|」。編輯器
8.3.1標準輸入與輸出spa
執行一個Shell命令行時一般會自動打開3個標準文件,如圖8.3所示。操作系統
圖 8.3 Shell執行時對應的3個標準文件命令行
標準輸入文件stdin,一般對應終端的鍵盤,標準輸出文件stdout和標準錯誤輸出文件stderr,這兩個文件都對應終端的屏幕。進程將從標準輸入文件中獲得輸入數據,將正常輸出數據輸出到標準輸出文件,而錯誤信息將打印到標準錯誤文件。進程
現以cat 命令爲例來介紹標準輸入與輸出。cat命令的功能是從命令行給出的文件中讀取數據,並將這些數據直接送到標準輸出文件,通常對應終端屏幕,如示例8-7所示。圖片
【示例8-7】ip
[root@CentOS ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
HWADDR=00:0C:29:7F:08:9D
TYPE=Ethernet
UUID=3268d86a-3245-4afa-94e0-f100a8efae44
ONBOOT=yes
BOOTPROTO=static
BROADCAST=192.168.3.255
IPADDR=192.168.3.100
NETMASK=255.255.255.0文檔
該命令會把文件ifcfg-eth0的內容顯示到標準輸出即屏幕上。若是cat命令行中沒有參數,會從標準輸入文件中通常對應鍵盤讀取數據,並將其送到標準輸出文件中,如示例8-8所示。
【示例8-8】
[root@CentOS ~]# cat
mycontent
mycontent
hello
hello
用戶輸入的每一行信息都會馬上被cat命令輸出到屏幕上。用戶對輸入的數據沒法作進一步地處理。爲解決這個問題,Linux操做系統爲輸入、輸出的傳送引入了另外兩種機制:輸入/輸出重定向和管道。
8.3.2輸入重定向
輸入重定向是指把命令或可執行程序的標準輸入重定向到指定的文件中。也就是輸入能夠不來自鍵盤,而來自一個指定的文件。輸入重定向主要用於改變一個命令的輸入源。
例如上個示例中的cat命令,當鍵入該命令後並無任何反應,從鍵盤輸入的全部文本都出如今屏幕上,直至按下Ctrl+d組合鍵,命令纔會終止,可採用兩種方法:一種是爲該命令給出一個文件名,另一種方法是使用輸入重定向。
輸入重定向的通常形式爲:命令<文件名,輸入重定向符號爲「<」。示例8-9演示了此種狀況,此示例中的文件已不是參數,而是標準輸入。
【示例8-9】
[root@CentOS ~]# cat< /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
HWADDR=00:0C:29:7F:08:9D
TYPE=Ethernet
UUID=3268d86a-3245-4afa-94e0-f100a8efae44
ONBOOT=yes
BOOTPROTO=static
BROADCAST=192.168.3.255
IPADDR=192.168.3.100
NETMASK=255.255.255.0
[root@CentOS ~]# wc </etc/sysconfig/network-scripts/ifcfg-eth0
99 188
還有一種輸入重定向,如示例8-10所示。
【示例8-10】
[root@CentOS ~]# cat <<EEE
line1
line2
line3
EEE
line1
line2
line3
標識符「EEE」表示輸入開始和結束的分隔符,此名稱不是固定的,可使用其餘字符串,主要是一個分隔的做用。文檔的重定向操做符爲「<<」。將一對分隔符之間的正文重定向輸入命令。例如上述示例中將「EEE」之間的內容做爲正文,而後做爲輸入傳給cat命令。因爲大多數命令都以參數的形式在命令行中指定輸入文件的文件名,因此輸入重定向並不常用。使用某些不能利用文件名做爲輸入參數的命令,須要的輸入內容又存在一個文件裏時,能夠用輸入重定向來解決問題。
8.3.3輸出重定向
輸出重定向是指把命令或可執行程序的標準輸出或標準錯誤輸出從新定向到指定文件中。命令的輸出不顯示在屏幕上,而是寫入到指定的文件中,以便之後的問題定位或其餘用途。輸出重定向比輸入重定向更經常使用,不少狀況下均可以使用這種功能。例如,若是某個命令的輸出不少,在屏幕上不能徹底顯示,那麼將輸出重定向到一個文件中,而後再用文本編輯器打開這個文件,就能夠查看輸出信息,若是想保存一個命令的輸出,也可使用這種方法。還有,輸出重定向可用於把一個命令的輸出看成另外一個命令的輸入,還有一種更簡單的方法,就是使用管道,管道將在下節介紹。
輸出重定向的通常格式爲:命令>文件名,即輸出重定向符號爲「>」,使用方法如示例8-11所示。
【示例8-11】
[root@CentOS ~]# ls -l / >dir.txt
[root@CentOS ~]# head-n5 dir.txt
total 114
dr-xr-xr-x.2 root root4096 Jun8 00:54 bin
dr-xr-xr-x.5 root root1024 Apr 13 00:33 boot
dr-xr-xr-x.7 root root4096 Mar6 02:33 cdrom
drwxr-xr-x.18 root root4096 Jun8 01:07 data
用「ls -l」命令顯示當前的目錄和文件,並把結果輸出到當前目錄下的dir.txt文件內,而不是顯示在屏幕上。查看dir.txt文件的內容可使用cat命令,注意是否與直接使用「ls -l」命令時的顯示結果相同。
注意:若是「>」符號後面的文件已存在,那麼這個文件將被覆蓋。
爲避免輸出重定向命令中指定的文件內容被覆蓋,Shell提供了輸出重定向的追加方法。輸出追加劇定向與輸出重定向的功能相似,區別僅在於輸出追加劇定向的功能是把命令或可執行程序的輸出結果追加到指定文件的最後,這時文件的原有內容不被覆蓋。追加劇定向操做符「>>」,格式爲:命令>>文件名,使用方法如示例8-12所示。
【示例8-12】
[root@CentOS ~]# ls-l /usr >>dir.txt
上述命令的輸出會追加在文件的末位,原來的內容不會被覆蓋。
8.3.4錯誤輸出重定向
和程序的標準輸出重定向同樣,程序的錯誤輸出也能夠從新定向。使用符號「2>」或追加符號「2>>」標識能夠對錯誤輸出重定向。如要將程序的任何錯誤信息打印到文件中,以備問題定位,可使用示例8-13中的方法。
【示例8-13】
[root@CentOS ~]# ls /xxxx
ls: cannot access /xxxx: No such file or directory
[root@CentOS ~]# ls /xxxx 1>stdout
ls: cannot access /xxxx: No such file or directory
[root@CentOS ~]# ls /xxxx 1>stdout 2>stderr
[root@CentOS ~]# cat stderr
ls: cannot access /xxxx: No such file or directory
[root@CentOS ~]# ls /xxxx 1>stdout 2>&1
[root@CentOS ~]# cat stdout
ls: cannot access /xxxx: No such file or directory
[root@CentOS ~]# ls /xxxxx &>stderr
[root@CentOS ~]# ls /xxxxx/ &>stdout
[root@CentOS ~]# head stdout
ls: cannot access /xxxxx: No such file or directory
/:
bin
boot
cdrom
因爲/xxxx目錄不存在,因此沒有標準輸出,只有錯誤輸出。上述示例首先演示了錯誤輸出的內容,當標準輸出被重定向後,標準錯誤輸出並無被重定向,因此錯誤輸出被打印到屏幕上。使用「2>stderr」將錯誤輸出定位到指定的文件中,另一種方法是將標準錯誤輸出重定向到標準輸出,執行後在屏幕上看不到任何內容,用cat命令查看文件的內容,看到上面命令的錯誤提示。還可使用另外一個輸出重定向操做符「&>」,其功能是將標準輸出和錯誤輸出送到同一文件中。表8-3列出了經常使用的輸入輸出重定向方法。
表8.3經常使用的重定向含義
參數
說明
command > filename
把標準輸出重定向到一個文件
command >> filename
把標準輸出追加劇定向到一個文件
command 1> fielname
把標準輸出重定向到一個文件
command > filename 2 > &1
把標準輸出和標準錯誤輸出重定向到一個文件
command 2 > filename
把標準錯誤輸出重定向到一個文件中
command < filename > filename2
以filename爲標準輸入,filename2爲標準輸出
command < filename
把filename做爲命令的標準輸入
command << delimiter
從標準輸入讀入數據,直到遇到delimiter爲止
8.3.5管道
將一個程序或命令的輸出做爲另外一個程序或命令的輸入,有兩種方法:一種是經過一個臨時文件將兩個命令或程序結合在一塊兒;另一種方法是使用管道。
管道能夠把一系列命令鏈接起來,能夠將前面命令的輸出做爲後面命令的輸入,第1個命令輸出利用管道傳給第2個命令,第2個命令的輸出又會做爲第3個命令的輸入,以此類推。若是命令行中未使用輸出重定向,顯示在屏幕上的是管道行中最後一個命令的輸出或其餘命令執行異常時致使的錯誤輸出。使用管道符「|」來創建一個管道行,用法如示例8-14所示。
【示例8-14】
[root@CentOS ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0|grep IPADD
IPADDR=192.168.3.100
[root@CentOS ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0|grep IPADD|awk -F= '{print $2}'
192.168.3.100
上述示例cat命令輸出的內容以管道的形式發送給grep命令,而後經過字符串匹配查找文件內容。
喜歡能夠購買《超容易的Linux系統管理入門書》。寫書評得獎品。