日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

shell十三問,為linux學(xué)習(xí)打基礎(chǔ)(三)

 mypkm 2016-10-21



本文整理并轉(zhuǎn)自CU上的帖子[學(xué)習(xí)共享] shell 十三問?,此貼是2003年發(fā)表的,但卻是相當(dāng)不錯(cuò)的linux基礎(chǔ)知識(shí)匯集貼,原帖主使用的臺(tái)灣風(fēng)格,本文加以簡體化和整理。

第11問:> 與 < 差在哪?

11.1

談到I/O redirection,不妨先讓我們認(rèn)識(shí)一下File Descriptor(FD)。程序的運(yùn)算,在大部份情況下都是進(jìn)行數(shù)據(jù)(data)的處理,這些數(shù)據(jù)從哪讀進(jìn)?又,送出到哪里呢?這就是File descriptor(FD)的功用了。

在shell程序中,最常使用的FD大概有三個(gè),分別為:

  • 0: Standard Input(STDIN)
  • 1: Standard Output(STDOUT)
  • 2: Standard Error Output(STDERR)

在標(biāo)準(zhǔn)情況下,這些FD分別跟如下設(shè)備(device)關(guān)聯(lián):

  • stdin(0):keyboard
  • stdout(1):monitor
  • stderr(2):monitor

我們可以用如下下命令測試一下:

$ mail -s test root
this is a test mail.
please skip.
^d(同時(shí)按crtl跟d鍵)

很明顯,mail程序所讀進(jìn)的數(shù)據(jù),就是從stdin也就是keyboard讀進(jìn)的。不過,不見得每個(gè)程序的stdin都跟mail一樣從keyboard讀進(jìn),因?yàn)槌绦蜃髡呖梢詮臋n案參數(shù)讀進(jìn)stdin,如:

$ cat /etc/passwd

但,要是cat之后沒有檔案參數(shù)則又如何呢?哦,請您自己玩玩看啰….^_^

$ cat

(請留意數(shù)據(jù)輸出到哪里去了,最后別忘了按^d離開…)至于stdout與stderr,嗯…等我有空再續(xù)吧…^_^ 還是,有哪位前輩要來玩接龍呢?

11.2

沿文再續(xù),書接上一回…^_^ 相信,經(jīng)過上一個(gè)練習(xí)后,你對stdin與stdout應(yīng)該不難理解吧?然后,讓我們繼續(xù)看stderr好了。

事實(shí)上,stderr沒甚么難理解的:說穿了就是“錯(cuò)誤信息”要往哪邊送而已…比方說,若讀進(jìn)的檔案參數(shù)是不存在的,那我們在monitor上就看到了:

$ ls no.such.file
ls: no.such.file: No such file or directory

若,一個(gè)命令同時(shí)產(chǎn)生stdout與stderr呢?那還不簡單,都送到monitor來就好了:

$ touch my.file
$ ls my.file no.such.file
ls: no.such.file: No such file or directory
my.file

okay,至此,關(guān)于FD及其名稱、還有相關(guān)聯(lián)的設(shè)備,相信你已經(jīng)沒問題了吧?那好,接下來讓我們看看如何改變這些FD的預(yù)設(shè)數(shù)據(jù)信道,我們可用<來改變讀進(jìn)的數(shù)據(jù)信道(stdin),使之從指定的檔案讀進(jìn)。我們可用>來改變送出的數(shù)據(jù)信道(stdout,stderr),使之輸出到指定的檔案。比方說:

$ cat < my.file

就是從my.file讀進(jìn)數(shù)據(jù)

$ mail -s test root < /etc/passwd

則是從/etc/passwd讀進(jìn)…

這樣一來,stdin將不再是從keyboard讀進(jìn),而是從檔案讀進(jìn)了…嚴(yán)格來說,<符號(hào)之前需要指定一個(gè)FD的(之間不能有空白),但因?yàn)?code style="margin: 0px 0.15em; padding: 0px 0.3em; border-radius: 3px; border: 1px solid rgb(234, 234, 234); border-image: none; font-family: Consolas, Inconsolata, Courier, monospace; font-size: 0.85em; display: inline; white-space: pre-wrap; background-color: rgb(248, 248, 248);">0是<的預(yù)設(shè)值,因此<0<是一樣的!okay,這個(gè)好理解吧?

那,要是用兩個(gè)<<又是啥呢?這是所謂的HERE Document,它可以讓我們輸入一段文本,直到讀到<<后指定的字串。比方說:

$ cat <<FINISH
first line here
second line there
third line nowhere
FINISH

這樣的話,cat會(huì)讀進(jìn)3行句子,而無需從keyboard讀進(jìn)數(shù)據(jù)且要等^d結(jié)束輸入。至>又如何呢?且聽下回分解…

11.3

okay,又到講古時(shí)間~~~當(dāng)你搞懂了0<原來就是改變stdin的數(shù)據(jù)輸入信道之后,相信要理解如下兩個(gè)redirection就不難了:1> 2> 。前者是改變stdout的數(shù)據(jù)輸出信道,后者是改變stderr的數(shù)據(jù)輸出信道。兩者都是將原本要送出到monitor的數(shù)據(jù)轉(zhuǎn)向輸出到指定檔案去。

由于1>的預(yù)設(shè)值,因此,1>>是相同的,都是改變stdout。用上次的ls例子來說明一下好了:

$ ls my.file no.such.file 1>file.out
ls: no.such.file: No such file or directory

這樣monitor就只剩下stderr而已。因?yàn)閟tdout給寫進(jìn)file.out去了。

$ ls my.file no.such.file 2>file.err
my.file

這樣monitor就只剩下stdout,因?yàn)閟tderr寫進(jìn)了file.err。

$ ls my.file no.such.file 1>file.out 2>file.err

這樣monitor就啥也沒有,因?yàn)閟tdout與stderr都給轉(zhuǎn)到檔案去了…

呵~~~看來要理解>一點(diǎn)也不難啦﹗是不?沒騙你吧?^_^ 不過,有些地方還是要注意一下的。
首先,是同時(shí)寫入的問題。比方如下這個(gè)例子:

$ ls my.file no.such.file 1>file.both 2>file.both

假如stdout(1)與stderr(2)都同時(shí)在寫入file.both的話,則是采取“覆蓋”方式:后來寫入的覆蓋前面的。讓我們假設(shè)一個(gè)stdout與stderr同時(shí)寫入file.out的情形好了:

  • 首先stdout寫入10個(gè)字元
  • 然后stderr寫入6個(gè)字元

那么,這時(shí)候原本stdout輸出的10個(gè)字元就被stderr覆蓋掉了。那,如何解決呢?所謂山不轉(zhuǎn)路轉(zhuǎn)、路不轉(zhuǎn)人轉(zhuǎn)嘛,我們可以換一個(gè)思維:將std