掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供霸州網(wǎng)站建設、霸州做網(wǎng)站、霸州網(wǎng)站設計、霸州網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、霸州企業(yè)網(wǎng)站模板建站服務,十多年霸州做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。
那么,什么是輸入輸出方向呢?標準的輸入輸出方向又是什么呢?
一般情況下,我們都是從鍵盤讀取用戶輸入的數(shù)據(jù),然后再把數(shù)據(jù)拿到程序(C語言程序、Shell 腳本程序等)中使用;這就是標準的輸入方向,也就是從鍵盤到程序。
反過來說,程序中也會產(chǎn)生數(shù)據(jù),這些數(shù)據(jù)一般都是直接呈現(xiàn)到顯示器上,這就是標準的輸出方向,也就是從程序到顯示器。
我們可以把觀點提煉一下,其實輸入輸出方向就是數(shù)據(jù)的流動方向:
計算機的硬件設備有很多,常見的輸入設備有鍵盤、鼠標、麥克風、手寫板等,輸出設備有顯示器、投影儀、打印機等。不過,在 Linux 中,標準輸入設備指的是鍵盤,標準輸出設備指的是顯示器。
Linux 中一切皆文件,包括標準輸入設備(鍵盤)和標準輸出設備(顯示器)在內(nèi)的所有計算機硬件都是文件。
為了表示和區(qū)分已經(jīng)打開的文件,Linux 會給每個文件分配一個 ID,這個 ID 就是一個整數(shù),被稱為
文件描述符(File Descriptor)。
| 文件描述符 | 文件名 | 類型 | 硬件 |
|---|---|---|---|
| 0 | stdin | 標準輸入文件 | 鍵盤 |
| 1 | stdout | 標準輸出文件 | 顯示器 |
| 2 | stderr | 標準錯誤輸出文件 | 顯示器 |
Linux 程序在執(zhí)行任何形式的 I/O 操作時,都是在讀取或者寫入一個文件描述符。一個文件描述符只是一個和打開的文件相關聯(lián)的整數(shù),它的背后可能是一個硬盤上的普通文件、FIFO、管道、終端、鍵盤、顯示器,甚至是一個網(wǎng)絡連接。
stdin、stdout、stderr 默認都是打開的,在重定向的過程中,0、1、2 這三個文件描述符可以直接使用。
輸出重定向是指命令的結果不再輸出到顯示器上,而是輸出到其它地方,一般是文件中。這樣做的最大好處就是把命令的結果保存起來,當我們需要的時候可以隨時查詢。Bash 支持的輸出重定向符號如下表所示。
| 類 型 | 符 號 | 作 用 |
|---|---|---|
| 標準輸出重定向 | command >file | 以覆蓋的方式,把 command 的正確輸出結果輸出到 file 文件中。 |
| command >>file | 以追加的方式,把 command 的正確輸出結果輸出到 file 文件中。 | |
| 標準錯誤輸出重定向 | command 2>file | 以覆蓋的方式,把 command 的錯誤信息輸出到 file 文件中。 |
| command 2>>file | 以追加的方式,把 command 的錯誤信息輸出到 file 文件中。 | |
| 正確輸出和錯誤信息同時保存 | command >file 2>&1 | 以覆蓋的方式,把正確輸出和錯誤信息同時保存到同一個文件(file)中。 |
| command >>file 2>&1 | 以追加的方式,把正確輸出和錯誤信息同時保存到同一個文件(file)中。 | |
| command >file1 2>file2 | 以覆蓋的方式,把正確的輸出結果輸出到 file1 文件中,把錯誤信息輸出到 file2 文件中。 | |
| command >>file1 2>>file2 | 以追加的方式,把正確的輸出結果輸出到 file1 文件中,把錯誤信息輸出到 file2 文件中。 | |
| command >file 2>file | 【不推薦】這兩種寫法會導致 file 被打開兩次,引起資源競爭,所以 stdout 和 stderr 會互相覆蓋,我們將在《結合Linux文件描述符談重定向,徹底理解重定向的本質(zhì)》一節(jié)中深入剖析。 | |
| command >>file 2>>file |
在輸出重定向中,
>代表的是覆蓋,
>>代表的是追加。
輸出重定向的完整寫法其實是
fd>file或者
fd>>file,其中 fd 表示文件描述符,如果不寫,默認為 1,也就是標準輸出文件。
當文件描述符為 1 時,一般都省略不寫,如上表所示;當然,如果你愿意,也可以將
command >file寫作
command 1>file,但這樣做是多此一舉。
當文件描述符為大于 1 的值時,比如 2,就必須寫上。
需要重點說明的是,
fd和
>之間不能有空格,否則 Shell 會解析失?。?br />
>和
file之間的空格可有可無。為了保持一致,我習慣在
>兩邊都不加空格。
下面的語句是一個反面教材:
echo "c.biancheng.net" 1 >log.txt
注意
1和
>之間的空格。echo 命令的輸出結果是
c.biancheng.net,我們的初衷是將輸出結果重定向到 log.txt,但是當你打開 log.txt 文件后,發(fā)現(xiàn)文件的內(nèi)容為
c.biancheng.net 1,這就是多余的空格導致的解析錯誤。也就是說,Shell 將該條語句理解成了下面的形式:
echo "c.biancheng.net" 1 1>log.txt
【實例1】將 echo 命令的輸出結果以追加的方式寫入到 demo.txt 文件中。
#!/bin/bash
for str in "C語言中文網(wǎng)" "http://c.biancheng.net/" "成立7年了" "日IP數(shù)萬"
do
echo $str >>demo.txt #將輸入結果以追加的方式重定向到文件
done
運行以上腳本,使用
cat demo.txt查看文件內(nèi)容,顯示如下:
C語言中文網(wǎng)
http://c.biancheng.net/
成立7年了
日IP數(shù)萬
【實例2】將
ls -l命令的輸出結果重定向到文件中。
[c.biancheng.net]$ ls -l #先預覽一下輸出結果 總用量 16 drwxr-xr-x. 2 root root 21 7月 1 2016 abc -rw-r--r--. 1 mozhiyan mozhiyan 399 3月 11 17:12 demo.sh -rw-rw-r--. 1 mozhiyan mozhiyan 67 3月 22 17:16 demo.txt -rw-rw-r--. 1 mozhiyan mozhiyan 278 3月 16 17:17 main.c -rwxr-xr-x. 1 mozhiyan mozhiyan 187 3月 22 17:16 test.sh [c.biancheng.net]$ ls -l >demo.txt #重定向 [c.biancheng.net]$ cat demo.txt #查看文件內(nèi)容 總用量 12 drwxr-xr-x. 2 root root 21 7月 1 2016 abc -rw-r--r--. 1 mozhiyan mozhiyan 399 3月 11 17:12 demo.sh -rw-rw-r--. 1 mozhiyan mozhiyan 0 3月 22 17:21 demo.txt -rw-rw-r--. 1 mozhiyan mozhiyan 278 3月 16 17:17 main.c -rwxr-xr-x. 1 mozhiyan mozhiyan 187 3月 22 17:16 test.sh
命令正確執(zhí)行是沒有錯誤信息的,我們必須刻意地讓命令執(zhí)行出錯,如下所示:
[c.biancheng.net]$ ls java #先預覽一下錯誤信息 ls: 無法訪問java: 沒有那個文件或目錄 [c.biancheng.net]$ ls java 2>err.log #重定向 [c.biancheng.net]$ cat err.log #查看文件 ls: 無法訪問java: 沒有那個文件或目錄
【實例1】把正確結果和錯誤信息都保存到一個文件中,例如:
[c.biancheng.net]$ ls -l >out.log 2>&1 [c.biancheng.net]$ ls java >>out.log 2>&1 [c.biancheng.net]$ cat out.log 總用量 12 drwxr-xr-x. 2 root root 21 7月 1 2016 abc -rw-r--r--. 1 mozhiyan mozhiyan 399 3月 11 17:12 demo.sh -rw-rw-r--. 1 mozhiyan mozhiyan 278 3月 16 17:17 main.c -rw-rw-r--. 1 mozhiyan mozhiyan 0 3月 22 17:39 out.log -rwxr-xr-x. 1 mozhiyan mozhiyan 187 3月 22 17:16 test.sh ls: 無法訪問java: 沒有那個文件或目錄
out.log 的最后一行是錯誤信息,其它行都是正確的輸出結果。
【實例2】上面的實例將正確結果和錯誤信息都寫入同一個文件中,這樣會導致視覺上的混亂,不利于以后的檢索,所以我建議把正確結果和錯誤信息分開保存到不同的文件中,也即寫成下面的形式:
ls -l >>out.log 2>>err.log
這樣一來,正確的輸出結果會寫入到 out.log,而錯誤的信息則會寫入到 err.log。
如果你既不想把命令的輸出結果保存到文件,也不想把命令的輸出結果顯示到屏幕上,干擾命令的執(zhí)行,那么可以把命令的所有結果重定向到 /dev/null 文件中。如下所示:
ls -l &>/dev/null
大家可以把 /dev/null 當成 Linux 系統(tǒng)的垃圾箱,任何放入垃圾箱的數(shù)據(jù)都會被丟棄,不能恢復。
輸入重定向就是改變輸入的方向,不再使用鍵盤作為命令輸入的來源,而是使用文件作為命令的輸入。
| 符號 | 說明 |
|---|---|
command | 將 file 文件中的內(nèi)容作為 command 的輸入。 |
|
command <| 從標準輸入(鍵盤)中讀取數(shù)據(jù),直到遇見分界符 END 才停止(分界符可以是任意的字符串,用戶自己定義)。 |
|
| command |
將 file1 作為 command 的輸入,并將 command 的處理結果輸出到 file2。 |
和輸出重定向類似,輸入重定向的完整寫法是
fd
【示例1】統(tǒng)計文檔中有多少行文字。
Linux wc 命令可以用來對文本進行統(tǒng)計,包括單詞個數(shù)、行數(shù)、字節(jié)數(shù),它的用法如下:
wc [選項] [文件名]
其中,
-c選項統(tǒng)計字節(jié)數(shù),
-w選項統(tǒng)計單詞數(shù),
-l選項統(tǒng)計行數(shù)。
統(tǒng)計 readme.txt 文件中有多少行文本:
[c.biancheng.net]$ cat readme.txt #預覽一下文件內(nèi)容 C語言中文網(wǎng) http://c.biancheng.net/ 成立7年了 日IP數(shù)萬 [c.biancheng.net]$ wc -l【實例2】逐行讀取文件內(nèi)容。
#!/bin/bash while read str; do echo $str done運行結果:
C語言中文網(wǎng)
http://c.biancheng.net/
成立7年了
日IP數(shù)萬這種寫法叫做代碼塊重定向,也就是把一組命令同時重定向到一個文件,我們將在《Shell代碼塊重定向》一節(jié)中詳細講解。
【實例3】統(tǒng)計用戶在終端輸入的文本的行數(shù)。
此處我們使用輸入重定向符號
<<,這個符號的作用是使用特定的分界符作為命令輸入的結束標志,而不使用 Ctrl+D 鍵。[c.biancheng.net]$ wc -l <123 > 789 > abc > xyz > END 4 wc 命令會一直等待用輸入,直到遇見分界符 END 才結束讀取。
<<之后的分界符可以自由定義,只要再碰到相同的分界符,兩個分界符之間的內(nèi)容將作為命令的輸入(不包括分界符本身)。

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流