網(wǎng)頁設(shè)計(jì)網(wǎng)站建設(shè)的基本流程關(guān)鍵詞工具有哪些
文章目錄
- 前言
- 一、重定向
- 二、系統(tǒng)調(diào)用dup2
- 三、重定向的使用
- 四、一切皆文件
前言
Linux進(jìn)程默認(rèn)情況下會(huì)有3個(gè)缺省打開的文件描述符,分別是標(biāo)準(zhǔn)輸入0, 標(biāo)準(zhǔn)輸出1, 標(biāo)準(zhǔn)錯(cuò)誤2, 0,1,2對(duì)應(yīng)的物理設(shè)備一般是:鍵盤,顯示器,顯示器
而現(xiàn)在知道,文件描述符就是從0開始的小整數(shù)。當(dāng)我們打開文件時(shí),操作系統(tǒng)在內(nèi)存中要?jiǎng)?chuàng)建相應(yīng)的數(shù)據(jù)結(jié)構(gòu)來描述目標(biāo)文件。于是就有了?le結(jié)構(gòu)體。表示一個(gè)已經(jīng)打開的文件對(duì)象。而進(jìn)程執(zhí)行open系統(tǒng)調(diào)用,所以必須讓進(jìn)程和文件關(guān)聯(lián)起來。每個(gè)進(jìn)程都有一個(gè)指針*?les, 指向一張表?les_struct,該表最重要的部分就是包涵一個(gè)指針數(shù)組,每個(gè)元素都是一個(gè)指向打開文件的指針!所以,本質(zhì)上,文件描述符就是該數(shù)組的下標(biāo)。所以,只要拿著文件描述符,就可以找到對(duì)應(yīng)的文件
一、重定向
文件描述符的分配規(guī)則:在files_struct數(shù)組當(dāng)中,找到當(dāng)前沒有被使用的
最小的一個(gè)下標(biāo),作為新的文件描述符。
我們先來看這段代碼
毫無疑問我們標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤占據(jù)了file數(shù)組0,1,2位置,然后我們執(zhí)行程序也是打印在顯示器上面
接下來我們?cè)賹?duì)源代碼進(jìn)行一些更改
我們執(zhí)行程序發(fā)現(xiàn)沒在顯示器上面打印信息,而是在文件里面打印了
而且此時(shí)的文件描述符為1,也驗(yàn)證了我們上面說的:
在files_struct數(shù)組當(dāng)中,找到當(dāng)前沒有被使用的
最小的一個(gè)下標(biāo),作為新的文件描述符。
原理:我printf默認(rèn)用標(biāo)準(zhǔn)輸出來封裝,而我標(biāo)準(zhǔn)輸出的文件描述符在數(shù)組中對(duì)應(yīng)的是1,我printf只管往1里面寫入,不關(guān)心你1里面到底是誰,所以當(dāng)我們關(guān)閉原來的文件描述符為1的標(biāo)準(zhǔn)輸出,我1位置就放入了myfile的文件指針,所以會(huì)向myfile中寫入
二、系統(tǒng)調(diào)用dup2
dup是duplicate的縮寫具有重定向的功能,(不需要我們像上面那樣復(fù)雜的先去關(guān)閉一個(gè)指定位置,再打開一個(gè)新文件的操作),之所以叫這個(gè)名字我們需要從原理層來看:
我們新打開的文件,操作系統(tǒng)創(chuàng)建fiile的結(jié)構(gòu)體并且其文件描述符分配為3,指針數(shù)組中下標(biāo)1位置直接對(duì)我們數(shù)組中下標(biāo)為3位置進(jìn)行拷貝,1位置最后也指向log.txt的文件結(jié)構(gòu)體
printf是C庫(kù)當(dāng)中的IO函數(shù),一般往 stdout 中輸出,但是stdout底層訪問文件的時(shí)候,找的還是fd:1, 但此時(shí),fd:1下標(biāo)所表示內(nèi)容,已經(jīng)變成了myfile的地址,不再是顯示器文件的地址,所以,輸出的任何消息都會(huì)往文件中寫入,進(jìn)而完成輸出重定向。
因?yàn)镮O相關(guān)函數(shù)與系統(tǒng)調(diào)用接口對(duì)應(yīng),并且?guī)旌瘮?shù)封裝系統(tǒng)調(diào)用,所以本質(zhì)上,訪問文件都是通過fd訪問的。所以C庫(kù)當(dāng)中的FILE結(jié)構(gòu)體內(nèi)部,必定封裝了fd。
三、重定向的使用
執(zhí)行文件:
我們會(huì)發(fā)現(xiàn)hello error沒有寫入log.txt中而是直接打印在了顯示器上這是為什么呢?
前面我們已經(jīng)有過重定向的知識(shí)了,這里應(yīng)該不難理解,
//本質(zhì)是將log.txt重定向到1也就是標(biāo)準(zhǔn)輸出流的位置,
完整寫法應(yīng)該是這樣的:
./test 1 > log.txt
因?yàn)槲募枋龇?span id="vxwlu0yf4" class="token number">1被重定向,所以我們朝stdout里寫入的數(shù)據(jù)雖然
依舊會(huì)向1所指向的位置
去寫入,但因?yàn)槲覀兊?span id="vxwlu0yf4" class="token number">1位置已經(jīng)被新文件重定向也就是1中存的是新文件的信息地址,
所以寫入的時(shí)候會(huì)寫入新文件的位置,這也就解釋了為什么log中會(huì)被寫入數(shù)據(jù)而我們stderror標(biāo)準(zhǔn)錯(cuò)誤流對(duì)應(yīng)的文件描述符2不受影響,
所以我依舊向顯示器打印
我們也可以選擇重定向到標(biāo)準(zhǔn)錯(cuò)誤對(duì)應(yīng)的文件描述符中
我們也可以將重定向1輸出到log.txt中剩余的內(nèi)容再重定向到文件描述符為2的位置
還可以同時(shí)把這些內(nèi)容輸入到一個(gè)文件當(dāng)中去
四、一切皆文件
即使是外設(shè),Linux中也會(huì)把他們看成文件,當(dāng)成文件來進(jìn)行管理
完整圖: