<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jasmine214--love

    只有當(dāng)你的內(nèi)心總是充滿快樂、美好的愿望和寧靜時,你才能擁有強壯的體魄和明朗、快樂或者寧靜的面容。
    posts - 731, comments - 60, trackbacks - 0, articles - 0
    最近在學(xué)習(xí)Unix下系統(tǒng)編程,書看的還比較仔細(xì),但是合上書后總是有種霧里看花朦朦朧朧的感覺。俗話說實踐出真知,學(xué)習(xí)編程怎么能不動手呢。既然是學(xué)習(xí)系統(tǒng)編程那就寫一些系統(tǒng)命令來鞏固知識,消除朦朧的感覺吧!選中PWD命令,有如下幾個原因:
              1、 可以加深對Linux文件系統(tǒng)組織結(jié)構(gòu)的理解
              2、 可以加深對目錄結(jié)構(gòu)的理解
              3、 可以加深對掛載點和鏈接的理解


    注:關(guān)于LINUX文件系統(tǒng)的相關(guān)基礎(chǔ)知識,大家可以先看看《Linux文件系統(tǒng)詳解》:http://www.armjishu.com/bbs/viewtopic.php?id=1754 &flag=1578

             Unix下一切皆文件,也就是說掌握好了文件也就掌握了Unix的一切(菜鳥說法不必當(dāng)真)。掌握了上述三個知識點也就算基本掌握了Unix文件系統(tǒng)的相關(guān)知識。有點遺憾的是文件狀態(tài)和權(quán)限相關(guān)知識在這個例子中沒有涉及。選好了命令下一步就是寫了,下面是我的寫作計劃:
    1、 Unix的文件系統(tǒng)的內(nèi)部結(jié)構(gòu),主要是超級塊、inode相關(guān)知識
    2、 目錄結(jié)構(gòu),當(dāng)然是目錄相關(guān)知識了
    3、 編寫PWD命令
             PWD命令的作用就是顯示當(dāng)前工作目錄的絕對路徑,就是從/開始到當(dāng)前目錄。用法很簡單,沒有其他參數(shù)。在命令行敲入pwd:

    點擊看大圖


    pwd命令.jpg



    1、Unix文件系統(tǒng)的內(nèi)部結(jié)構(gòu)
        文件系統(tǒng)可以用來存儲文件內(nèi)容、文件屬性(所有者、日期等)和目錄,這些不同類型的數(shù)據(jù)是如何存儲在磁盤上的呢?Linux使用了一個簡單的辦法。如下圖所示它將磁盤分成了3部分:超級塊、inode表和數(shù)據(jù)區(qū)。

    點擊看大圖


    文件的內(nèi)部結(jié)構(gòu)



          超級塊,通常是文件系統(tǒng)的第一個塊,用來存放文件系統(tǒng)本身的信息。例如每個區(qū)域的大小、未被使用的磁盤塊的信息等;不同版本的Unix的超級塊的內(nèi)容和結(jié)構(gòu)稍有不同。
          inode表,每個文件都有一些屬性,如大小、文件所有者和最近修改時間等。這些屬性被記錄在inode表中,所有的inode都有相同的大小。文件系統(tǒng)中的每個文件都對應(yīng)一個inode;
          數(shù)據(jù)區(qū),文件內(nèi)容的內(nèi)容保存在這個區(qū)域。磁盤上所有塊的大小都是一樣的,如果文件包含了超過一個塊的內(nèi)容,則文件內(nèi)容會存放在多個磁盤塊中。
          當(dāng)創(chuàng)建一個新文件時,內(nèi)核將文件內(nèi)容存放在數(shù)據(jù)區(qū),文件屬性存放在inode中,文件名存放在目錄中。當(dāng)對一個文件進行相關(guān)操作時,內(nèi)核先在目錄中找到 文件名,然后根據(jù)目錄中inode獲得文件的屬性,最終找到文件的內(nèi)容。從上述過程可以看出,目錄至少需要包含inode和文件名。

    2、目錄結(jié)構(gòu)
       用戶看到的文件系統(tǒng)是目錄和子目錄的集合,也就是目錄樹。每個目錄能夠包含文件和子目錄,每個子目錄有一個父目錄,這棵樹的結(jié)構(gòu)常用線條連接的方框圖來 表示。在文件系統(tǒng)內(nèi)部,目錄是一個包含文件名與inode節(jié)點對的列表的文件。從用戶角度看到的是一個文件名的列表,而從系統(tǒng)的角度看到的是一個被命名的 指針的列表。如下圖所示:

    點擊看大圖


    目錄樹的兩種不同視圖



          一般我們都說文件存放在某個目錄中,但是由上面的分析可知目錄中存放的只是文件在inode表的入口,而文件內(nèi)容則存儲在數(shù)據(jù)區(qū)。'文件x在目錄a中 ',意味著在目錄a中有一個指向inode402的鏈接,這個鏈接所附加的文件名為x。簡短的說,目錄包含的是文件的引用,每個引用被稱為鏈接。
          鏈接有兩種,一種是硬鏈接,另一種是符號鏈接。這里需要注意的一點是Unix下文件沒有文件名,但是鏈接有名字,通常所說的文件名其實就是鏈接名。硬鏈 接就是把鏈接名和inode鏈接起來,也就是將文件名和文件本身鏈接起來。符號鏈接就是通過名字引用文件,而不是inode,也就是將名字和名字鏈接起 來。
          從圖1我們可以看到,在系統(tǒng)角度,每個目錄都有兩個鏈接:'.'和'..'。這兩個鏈接是干什么用的呢?內(nèi)核在每個目錄都設(shè)置了一個指向目錄本身的inode,這個入口被稱為'.'。'..',是指向父目錄inode的入口。

    3、編寫PWD命令
    3.1、PWD分析
          通過前面基礎(chǔ)知識的學(xué)習(xí),我們知道了Unix文件系統(tǒng)是樹形結(jié)構(gòu),節(jié)點被稱為inode,指針的集合被稱為目錄,葉子節(jié)點被稱為鏈接。那么要想取得當(dāng)前 工作目錄的絕對路徑只需追蹤鏈接,讀取目錄,一個目錄接著一個目錄沿著樹向上追蹤,每步查看'.'的inode,然后在父目錄中查找該inode的名字, 直到到達樹的根部。這就是PWD命令的工作原理,知道了原理那么就可以得出PWD的實現(xiàn)算法了:
               1、得到'.'的inode,稱其為n(使用stat)
               2、進入'..'(使用chdir)
               3、找到節(jié)點號為n的inode鏈接的名字(使用opendir、readdir、closedir)
               4、重復(fù)上述三個步驟,直到到達書的根部
            這里需要注意兩個問題,第一個問題就是如何知道已經(jīng)到達樹的頂端。在Unix 文件系統(tǒng)的根目錄中,'.' 和 '..'指向同一個inode。因此當(dāng)PWD命令重復(fù)循環(huán)直到一個目錄的'.' 和 '..'的inode相同時,就可以認(rèn)為已經(jīng)到達文件樹的根部了。第二個問題就是如何以正確的順序顯示目錄名字。學(xué)過算法的同學(xué)都知道,處理這種問題用遞歸再合適不過了。通過一個遞歸的程序逐步到達樹的頂端來一個接一個地顯示目錄名,從而避免了字符串的管理。

    3.2、相關(guān)數(shù)據(jù)結(jié)構(gòu)和系統(tǒng)調(diào)用
        在動手寫代碼之前需要了解一下兩個數(shù)據(jù)結(jié)構(gòu):DIR和struct dirent。DIR是一個不透明的結(jié)構(gòu),每個平臺都有自己的DIR實現(xiàn),用戶不需要明白DIR的具體結(jié)構(gòu)。也就是說,看到源碼中的DIR就只需要明白這是個目錄指針就可以了。struct dirent是一個目錄入口的結(jié)構(gòu),在Linux下定義如下:

    1. struct dirent{  
    2.     long d_ino;   /* inode number 索引節(jié)點號 */  
    3.     off_t d_off;  /* offset to this dirent 在目錄文件中的偏移 */  
    4.     unsigned short d_reclen;    /* length of this d_name 文件名長 */  
    5.     unsigned char d_type;        /* the type of d_name 文件類型 */  
    6.     char d_name [NAME_MAX+1];   /* file name文件名,最長255字符 */  
    7. }  

    與目錄操作有關(guān)的函數(shù)在dirent.h頭文件中聲明。它們以DIR結(jié)構(gòu)為目錄操作的基礎(chǔ),其使用方法與文件流(FILE *)類似。目錄數(shù)據(jù)項本身在struct dirent結(jié)構(gòu)中返回。我們實現(xiàn)PWD命令需要用到的目錄操作有opendir、readdir和closedir,下面就介紹下這三個函數(shù):

    DIR *opendir(const char *name)
    opendir函數(shù)用來打開一個目錄并創(chuàng)建一個目錄流,如果成功則返回一個指向DIR結(jié)構(gòu)的指針,該指針用于讀取目錄數(shù)據(jù)項。

    struct dirent *readdir(DIR *dirp)
    readdir函數(shù)返回一個指針,指針指向的結(jié)構(gòu)保存著目錄流dirp中下一個目錄項的相關(guān)資料。后續(xù)的readdir調(diào)用將返回后續(xù)的目錄項。

    int closedir(DIR *dirp)
    closedir函數(shù)用來關(guān)閉一個目錄流并釋放與之相關(guān)的資源,成功返回0,失敗返回-1。

    3.3、編譯運行
         進入到存放spwd.c文件的目錄下,使用gcc編譯源文件,生成可執(zhí)行文件(我這里命名為spwd),然后把可執(zhí)行文件拷貝到/bin/下就可以像使用pwd命令一樣使用自己寫的pwd命令了。

    點擊看大圖


    112.JPG


    原文: http://blog.csdn.net/humchx/archive/2009/09/04/4517828.aspx


    主站蜘蛛池模板: 51视频精品全部免费最新| 成人免费视频软件网站| 亚洲国产成人精品青青草原| 久久久久久久91精品免费观看| 久久乐国产综合亚洲精品| 亚洲日韩人妻第一页| 91成人免费观看| 美女视频黄视大全视频免费的| 亚洲国产精品福利片在线观看| 大地资源在线观看免费高清| 四虎影视在线看免费观看| 亚洲精品第一国产综合精品| 免费国产美女爽到喷出水来视频| 国产精品免费高清在线观看| 亚洲精品无码久久久久久| 亚洲AV永久纯肉无码精品动漫| 在线免费观看污网站| 日本黄色动图免费在线观看| 亚洲成av人片在www鸭子| 亚洲AV无码成人网站久久精品大 | 亚洲狠狠综合久久| 日韩视频在线免费观看| 无码中文字幕av免费放dvd| 免费毛片毛片网址| 激情综合亚洲色婷婷五月| 亚洲中文字幕无码不卡电影| 在线观看免费宅男视频| 91麻豆国产免费观看| 国产成人无码精品久久久免费 | 亚洲国产乱码最新视频 | 噜噜噜亚洲色成人网站| 亚洲激情视频网站| 亚洲人成影院在线无码按摩店| 日本特黄特黄刺激大片免费| 亚洲美女视频免费| 久久精品乱子伦免费| 一级毛片免费毛片毛片| 久久精品国产亚洲av瑜伽| 激情亚洲一区国产精品| 亚洲最大在线视频| 久久综合亚洲鲁鲁五月天|