在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Linux/ 重定向
網(wǎng)絡系統(tǒng)
打印
重定向
使用命令
位置參數(shù)
權(quán)限
文本處理
疑難排解
layout: book-zh title: 自定制 shell 提示符
查找文件
layout: book-zh title: vi 簡介
shell 環(huán)境
什么是 shell
編譯程序
鍵盤高級操作技巧
流程控制:case 分支
流程控制:if 分支結(jié)構(gòu)
layout: book-zh title: 軟件包管理
進程
存儲媒介
格式化輸出
編寫第一個 Shell 腳本
啟動一個項目
流程控制:while/until 循環(huán)
文件系統(tǒng)中跳轉(zhuǎn)
字符串和數(shù)字
讀取鍵盤輸入
歸檔和備份
探究操作系統(tǒng)
流程控制:for 循環(huán)
自頂向下設計
數(shù)組
操作文件和目錄
奇珍異寶
從 shell 眼中看世界
正則表達式

重定向

這堂課,我們來介紹可能是命令行最酷的特性。它叫做 I/O 重定向。"I/O"代表輸入/輸出, 通過這個工具,你可以重定向命令的輸入輸出,命令的輸入來自文件,而輸出也存到文件。 也可以把多個命令連接起來組成一個強大的命令管道。為了炫耀這個工具,我們將敘述 以下命令:

  • cat - 連接文件

  • sort - 排序文本行

  • uniq - 報道或省略重復行

  • grep - 打印匹配行

  • wc - 打印文件中換行符,字,和字節(jié)個數(shù)

  • head - 輸出文件第一部分

  • tail - 輸出文件最后一部分

標準輸入,輸出,和錯誤

到目前為止,我們用到的許多程序都會產(chǎn)生某種輸出。這種輸出,經(jīng)常由兩種類型組成。 第一,程序運行結(jié)果;這是說,程序要完成的功能。第二,我們得到狀態(tài)和錯誤信息, 這些告訴我們程序進展。如果我們觀察一個命令,像 ls,會看到它的運行結(jié)果和錯誤信息 顯示在屏幕上。

與 Unix 主題“任何東西都是一個文件”保持一致,程序,比方說 ls,實際上把他們的運行結(jié)果 輸送到一個叫做標準輸出的特殊文件(經(jīng)常用 stdout 表示),而它們的狀態(tài)信息則送到另一個 叫做標準錯誤的文件(stderr)。默認情況下,標準輸出和標準錯誤都連接到屏幕,而不是 保存到磁盤文件。除此之外,許多程序從一個叫做標準輸入(stdin)的設備得到輸入,默認情況下, 標準輸入連接到鍵盤。

I/O 重定向允許我們可以更改輸出走向和輸入來向。一般地,輸出送到屏幕,輸入來自鍵盤, 但是通過 I/O 重定向,我們可以改變輸入輸出方向。

重定向標準輸出

I/O 重定向允許我們來重定義標準輸出送到哪里。重定向標準輸出到另一個文件除了屏幕,我們使用 ">" 重定向符,其后跟著文件名。為什么我們要這樣做呢?因為有時候把一個命令的運行結(jié)果存儲到 一個文件很有用處。例如,我們可以告訴 shell 把 ls 命令的運行結(jié)果輸送到文件 ls-output.txt 中去, 由文件代替屏幕。

[me@linuxbox ~]$ ls -l /usr/bin > ls-output.txt

這里,我們創(chuàng)建了一個長長的目錄/usr/bin 列表,并且輸送程序運行結(jié)果到文件 ls-output.txt 中。 我們檢查一下重定向的命令輸出結(jié)果:

[me@linuxbox ~]$ ls -l ls-output.txt
-rw-rw-r-- 1   me   me    167878 2008-02-01 15:07 ls-output.txt

好;一個不錯的大型文本文件。如果我們用 less 閱讀器來查看這個文件,我們會看到文件 ls-output.txt 的確包含 ls 命令的執(zhí)行結(jié)果。

[me@linuxbox ~]$ less ls-output.txt

現(xiàn)在,重復我們的重定向測試,但這次有改動。我們把目錄換成一個不存在的目錄。

[me@linuxbox ~]$ ls -l /bin/usr > ls-output.txt
ls: cannot access /bin/usr: No such file or directory

我們收到一個錯誤信息。這很有意義,因為我們指定了一個不存在的目錄/bin/usr, 但是為什么這條錯誤信息顯示在屏幕上而不是被重定向到文件 ls-output.txt?答案是, ls 程序不把它的錯誤信息輸送到標準輸出。反而,像許多寫得不錯的 Unix 程序,ls 把 錯誤信息送到標準錯誤。因為我們只是重定向了標準輸出,而沒有重定向標準錯誤, 所以錯誤信息被送到屏幕。馬上,我們將知道怎樣重定向標準錯誤,但是首先看一下 我們的輸出文件發(fā)生了什么事情。

me@linuxbox ~]$ ls -l ls-output.txt
-rw-rw-r-- 1 me   me    0 2008-02-01 15:08 ls-output.txt

文件長度成為零!這是因為,當我們使用 ">" 重定向符來重定向輸出結(jié)果時,目標文件總是從開頭被重寫。 因為我們 ls 命令沒有產(chǎn)生運行結(jié)果,只有錯誤信息,重定向操作開始重寫文件,然后 由于錯誤而停止,導致文件內(nèi)容刪除。事實上,如果我們需要刪除一個文件內(nèi)容(或者創(chuàng)建一個 新的空文件),可以使用這樣的技巧:

[me@linuxbox ~]$ > ls-output.txt

簡單地使用重定向符,沒有命令在它之前,這會刪除一個已存在文件的內(nèi)容或是 創(chuàng)建一個新的空文件。

所以,怎樣才能把重定向結(jié)果追加到文件內(nèi)容后面,而不是從開頭重寫文件?為了這個目的, 我們使用">>"重定向符,像這樣:

[me@linuxbox ~]$ ls -l /usr/bin >> ls-output.txt

使用">>"操作符,將導致輸出結(jié)果添加到文件內(nèi)容之后。如果文件不存在,文件會 被創(chuàng)建,就如使用了">"操作符。把它放到測試中:

[me@linuxbox ~]$ ls -l /usr/bin >> ls-output.txt
[me@linuxbox ~]$ ls -l ls-output.txt
-rw-rw-r-- 1 me   me    503634 2008-02-01 15:45 ls-output.txt

我們重復執(zhí)行命令三次,導致輸出文件大小是原來的三倍。

重定向標準錯誤

重定向標準錯誤缺乏專用的重定向操作符。重定向標準錯誤,我們必須參考它的文件描述符。 一個程序可以在幾個編號的文件流中的任一個上產(chǎn)生輸出。然而我們必須把這些文件流的前 三個看作標準輸入,輸出和錯誤,shell 內(nèi)部參考它們?yōu)槲募枋龇?,1和2,各自地。shell 提供 了一種表示法來重定向文件,使用文件描述符。因為標準錯誤和文件描述符2一樣,我們用這種 表示法來重定向標準錯誤:

[me@linuxbox ~]$ ls -l /bin/usr 2> ls-error.txt

文件描述符"2",緊挨著放在重定向操作符之前,來執(zhí)行重定向標準錯誤到文件 ls-error.txt 任務。

重定向標準輸出和錯誤到同一個文件

可能有這種情況,我們希望捕捉一個命令的所有輸出到一個文件。為了完成這個,我們 必須同時重定向標準輸出和標準錯誤。有兩種方法來完成任務。第一個,傳統(tǒng)的方法, 在舊版本 shell 中也有效:

[me@linuxbox ~]$ ls -l /bin/usr > ls-output.txt 2>&1

使用這種方法,我們完成兩個重定向。首先重定向標準輸出到文件 ls-output.txt,然后 重定向文件描述符2(標準錯誤)到文件描述符1(標準輸出)使用表示法2>&1。


注意重定向的順序安排非常重要。標準錯誤的重定向必須總是出現(xiàn)在標準輸出 重定向之后,要不然它不起作用。上面的例子,

>ls-output.txt 2>&1

重定向標準錯誤到文件 ls-output.txt,但是如果命令順序改為:

2>&1 >ls-output.txt

則標準錯誤定向到屏幕。


現(xiàn)在的 bash 版本提供了第二種方法,更精簡合理的方法來執(zhí)行這種聯(lián)合的重定向。

[me@linuxbox ~]$ ls -l /bin/usr &> ls-output.txt

在這個例子里面,我們使用單單一個表示法 &> 來重定向標準輸出和錯誤到文件 ls-output.txt。

處理不需要的輸出

有時候“沉默是金”,我們不想要一個命令的輸出結(jié)果,只想把它們?nèi)拥?。這種情況 尤其適用于錯誤和狀態(tài)信息。系統(tǒng)為我們提供了解決問題的方法,通過重定向輸出結(jié)果 到一個特殊的叫做"/dev/null"的文件。這個文件是系統(tǒng)設備,叫做位存儲桶,它可以 接受輸入,并且對輸入不做任何處理。為了隱瞞命令錯誤信息,我們這樣做:

[me@linuxbox ~]$ ls -l /bin/usr 2> /dev/null

Unix 文化中的/dev/null

位存儲桶是個古老的 Unix 概念,由于它的普遍性,它的身影出現(xiàn)在 Unix 文化的 許多部分。當有人說他/她正在發(fā)送你的評論到/dev/null,現(xiàn)在你應該知道那是 什么意思了。更多的例子,可以閱讀 Wikipedia 關(guān)于"/dev/null"的文章。

重定向標準輸入

到目前為止,我們還沒有遇到一個命令是利用標準輸入的(實際上我們遇到過了,但是 一會兒再揭曉謎底),所以我們需要介紹一個。

cat - 連接文件

cat 命令讀取一個或多個文件,然后復制它們到標準輸出,就像這樣:

cat [file]

在大多數(shù)情況下,你可以認為 cat 命令相似于 DOS 中的 TYPE 命令。你可以使用 cat 來顯示 文件而沒有分頁,例如:

[me@linuxbox ~]$ cat ls-output.txt

將會顯示文件 ls-output.txt 的內(nèi)容。cat 經(jīng)常被用來顯示簡短的文本文件。因為 cat 可以 接受不只一個文件作為參數(shù),所以它也可以用來把文件連接在一起。比方說我們下載了一個 大型文件,這個文件被分離成多個部分(USENET 中的多媒體文件經(jīng)常以這種方式分離), 我們想把它們連起來。如果文件命名為:

我們能用這個命令把它們連接起來:

cat movie.mpeg.0* > movie.mpeg

因為通配符總是以有序的方式展開,所以這些參數(shù)會以正確順序安排。

這很好,但是這和標準輸入有什么關(guān)系呢?沒有任何關(guān)系,讓我們試著做些其他的工作。 如果我們輸入不帶參數(shù)的"cat"命令,會發(fā)生什么呢:

[me@linuxbox ~]$ cat

沒有發(fā)生任何事情,它只是坐在那里,好像掛掉了一樣??雌饋硎悄菢樱撬谧鏊撟龅氖虑椋?/p>

如果 cat 沒有給出任何參數(shù),它會從標準輸入讀入數(shù)據(jù),因為標準輸入,默認情況下,連接到鍵盤。 它正在等待我們輸入數(shù)據(jù)!試試這個:

[me@linuxbox ~]$ cat
The quick brown fox jumped over the lazy dog.

下一步,輸入 Ctrl-d(按住 Ctrl 鍵同時按下"d"),來告訴 cat,在標準輸入中, 它已經(jīng)到達文件末尾(EOF):

[me@linuxbox ~]$ cat
The quick brown fox jumped over the lazy dog.

由于文件名參數(shù)的缺席,cat 復制標準輸入到標準輸出,所以我們看到文本行重復出現(xiàn)。 我們可以使用這種行為來創(chuàng)建簡短的文本文件。比方說,我們想創(chuàng)建一個叫做"lazy_dog.txt" 的文件,這個文件包含例子中的文本。我們這樣做:

[me@linuxbox ~]$ cat > lazy_dog.txt
The quick brown fox jumped over the lazy dog.

輸入命令,其后輸入要放入文件中的文本。記住,最后輸入 Ctrl-d。通過使用這個命令,我們 實現(xiàn)了世界上最低能的文字處理器!看一下運行結(jié)果,我們使用 cat 來復制文件內(nèi)容到 標準輸出:

[me@linuxbox ~]$ cat lazy_dog.txt
The quick brown fox jumped over the lazy dog.

現(xiàn)在我們知道怎講接受標準輸入,除了文件名參數(shù),讓我們試著重定向標準輸入:

[me@linuxbox ~]$ cat < lazy_dog.txt
The quick brown fox jumped over the lazy dog.

使用“<”重定向操作符,我們把標準輸入源從鍵盤改到文件 lazy_dog.tx。我們看到結(jié)果 和傳遞單個文件名作為參數(shù)的執(zhí)行結(jié)果一樣。把這和傳遞一個文件名參數(shù)作比較,尤其沒有意義, 但它是用來說明把一個文件作為標準輸入源。

在我們繼續(xù)之前,查看 cat 的手冊頁,因為它有幾個有趣的選項。

管道線

命令可以從標準輸入讀取數(shù)據(jù),然后再把數(shù)據(jù)輸送到標準輸出,命令的這種能力被 一個 shell 特性所利用,這個特性叫做管道線。使用管道操作符"|"(豎杠),一個命令的 標準輸出可以管道到另一個命令的標準輸入:

command1 | command2

為了全面地說明這個命令,我們需要一些命令。是否記得我們說過,我們已經(jīng)知道有一個 命令接受標準輸入?它是 less 命令。我們用 less 來一頁一頁地顯示任何命令的輸出,命令把 它的運行結(jié)果輸送到標準輸出:

[me@linuxbox ~]$ ls -l /usr/bin | less

這極其方便!使用這項技術(shù),我們可以方便地檢測會產(chǎn)生標準輸出的任一命令的運行結(jié)果。

過濾器

管道線經(jīng)常用來對數(shù)據(jù)完成復雜的操作。有可能會把幾個命令放在一起組成一個管道線。 通常,以這種方式使用的命令被稱為過濾器。過濾器接受輸入,以某種方式改變它,然后 輸出它。第一個我們想試驗的過濾器是 sort。想象一下,我們想把目錄/bin 和/usr/bin 中 的可執(zhí)行程序都聯(lián)合在一起,再把它們排序,然后瀏覽執(zhí)行結(jié)果:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | less

因為我們指定了兩個目錄(/bin 和/usr/bin),ls 命令的輸出結(jié)果由有序列表組成, 各自針對一個目錄。通過在管道線中包含 sort,我們改變輸出數(shù)據(jù),從而產(chǎn)生一個 有序列表。

uniq - 報道或忽略重復行

uniq 命令經(jīng)常和 sort 命令結(jié)合在一起使用。uniq 從標準輸入或單個文件名參數(shù)接受數(shù)據(jù)有序 列表(詳情查看 uniq 手冊頁),默認情況下,從數(shù)據(jù)列表中刪除任何重復行。所以,為了確信 我們的列表中不包含重復句子(這是說,出現(xiàn)在目錄/bin 和/usr/bin 中重名的程序),我們添加 uniq 到我們的管道線中:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq | less

在這個例子中,我們使用 uniq 從 sort 命令的輸出結(jié)果中,來刪除任何重復行。如果我們想看到 重復的數(shù)據(jù)列表,讓 uniq 命令帶上"-d"選項,就像這樣:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq -d | less

wc - 打印行,字和字節(jié)數(shù)

wc(字計數(shù))命令是用來顯示文件所包含的行,字和字節(jié)數(shù)。例如:

[me@linuxbox ~]$ wc ls-output.txt
7902 64566 503634 ls-output.txt

在這個例子中,wc 打印出來三個數(shù)字:包含在文件 ls-output.txt 中的行數(shù),單詞數(shù)和字節(jié)數(shù), 正如我們先前的命令,如果 wc 不帶命令行參數(shù),它接受標準輸入。"-l"選項限制命令輸出只能 報道行數(shù)。添加 wc 到管道線來統(tǒng)計數(shù)據(jù),是個很便利的方法。查看我們的有序列表中程序個數(shù), 我們可以這樣做:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq | wc -l
2728

grep - 打印匹配行

grep 是個很強大的程序,用來找到文件中的匹配文本。這樣使用 grep 命令:

grep pattern [file...]

當 grep 遇到一個文件中的匹配"模式",它會打印出包含這個類型的行。grep 能夠匹配的模式可以 很復雜,但是現(xiàn)在我們把注意力集中在簡單文本匹配上面。在后面的章節(jié)中,我們將會研究 高級模式,叫做正則表達式。

比如說,我們想在我們的程序列表中,找到文件名中包含單詞"zip"的所有文件。這樣一個搜索, 可能讓我們了解系統(tǒng)中的一些程序與文件壓縮有關(guān)系。這樣做:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq | grep zip
bunzip2
bzip2
gunzip
...

grep 有-對方便的選項:"-i"導致 grep 忽略大小寫當執(zhí)行搜索時(通常,搜索是大小寫 敏感的),"-v"選項會告訴 grep 只打印不匹配的行。

head / tail - 打印文件開頭部分/結(jié)尾部分

有時候你不需要一個命令的所有輸出??赡苣阒幌胍皫仔谢蛘吆髱仔械妮敵鰞?nèi)容。 head 命令打印文件的前十行,而 tail 命令打印文件的后十行。默認情況下,兩個命令 都打印十行文本,但是可以通過"-n"選項來調(diào)整命令打印的行數(shù)。

[me@linuxbox ~]$ head -n 5 ls-output.txt
total 343496
...
[me@linuxbox ~]$ tail -n 5 ls-output.txt
...

它們也能用在管道線中:

[me@linuxbox ~]$ ls /usr/bin | tail -n 5
znew
...

tail 有一個選項允許你實時的瀏覽文件。當觀察日志文件的進展時,這很有用,因為 它們同時在被寫入。在以下的例子里,我們要查看目錄/var/log 里面的信息文件。在 一些 Linux 發(fā)行版中,要求有超級用戶權(quán)限才能閱讀這些文件,因為文件/var/log/messages 可能包含安全信息。

[me@linuxbox ~]$ tail -f /var/log/messages
Feb 8 13:40:05 twin4 dhclient: DHCPACK from 192.168.1.1
....

使用"-f"選項,tail 命令繼續(xù)監(jiān)測這個文件,當新的內(nèi)容添加到文件后,它們會立即 出現(xiàn)在屏幕上。這會一直繼續(xù)下去直到你輸入 Ctrl-c。

tee - 從 Stdin 讀取數(shù)據(jù),并同時輸出到 Stdout 和文件

為了和我們的管道隱喻保持一致,Linux 提供了一個叫做 tee 的命令,這個命令制造了 一個"tee",安裝到我們的管道上。tee 程序從標準輸入讀入數(shù)據(jù),并且同時復制數(shù)據(jù) 到標準輸出(允許數(shù)據(jù)繼續(xù)隨著管道線流動)和一個或多個文件。當在某個中間處理 階段來捕捉一個管道線的內(nèi)容時,這很有幫助。這里,我們重復執(zhí)行一個先前的例子, 這次包含 tee 命令,在 grep 過濾管道線的內(nèi)容之前,來捕捉整個目錄列表到文件 ls.txt:

[me@linuxbox ~]$ ls /usr/bin | tee ls.txt | grep zip
bunzip2
bzip2
....

總結(jié)歸納

一如既往,查看這章學到的每一個命令的文檔。我們已經(jīng)知道了他們最基本的用法。 它們還有很多有趣的選項。隨著我們 Linux 經(jīng)驗的積累,我們會了解命令行重定向特性 在解決特殊問題時非常有用處。有許多命令利用標準輸入和輸出,而幾乎所有的命令行 程序都使用標準錯誤來顯示它們的詳細信息。

Linux 可以激發(fā)我們的想象

當我被要求解釋 Windows 與 Linux 之間的差異時,我經(jīng)常拿玩具來作比喻。

Windows 就像一個游戲機。你去商店,買了一個包裝在盒子里面的全新的游戲機。 你把它帶回家,打開盒子,開始玩游戲。精美的畫面,動人的聲音。玩了一段時間之后, 你厭倦了它自帶的游戲,所以你返回商店,又買了另一個游戲機。這個過程反復重復。 最后,你玩膩了游戲機自帶的游戲,你回到商店,告訴售貨員,“我想要一個這樣的游戲!” 但售貨員告訴你沒有這樣的游戲存在,因為它沒有“市場需求”。然后你說,“但是我只 需要修改一下這個游戲!“,售貨員又告訴你不能修改它。所有游戲都被封裝在它們的 存儲器中。到頭來,你發(fā)現(xiàn)你的玩具只局限于別人為你規(guī)定好的游戲。

另一方面,Linux 就像一個全世界上最大的建造模型。你打開它,發(fā)現(xiàn)它只是一個巨大的 部件集合。有許多鋼支柱,螺釘,螺母,齒輪,滑輪,發(fā)動機,和一些怎樣來建造它的說明書。 然后你開始擺弄它。你建造了一個又一個樣板模型。過了一會兒,你發(fā)現(xiàn)你要建造自己的模型。 你不必返回商店,因為你已經(jīng)擁有了你需要的一切。建造模型以你構(gòu)想的形狀為模板,搭建 你想要的模型。

當然,選擇哪一個玩具,是你的事情,那么你覺得哪個玩具更令人滿意呢?