如果要實(shí)現(xiàn)pwd命令,必需對(duì)linux的文件系統(tǒng)非常了解。下面我們先從文件系統(tǒng)說(shuō)起,然后過(guò)度到編寫pwd的知識(shí)。
1、linux的文件系統(tǒng)
從用戶的角度來(lái)看,linux的文件系統(tǒng)就是一個(gè)目錄樹,從系統(tǒng)的角度看,是對(duì)磁盤劃分的抽象。磁盤的第一級(jí)抽象:從磁盤到分區(qū);第二級(jí):從磁盤到塊序
列,盤片被劃分為磁道,磁道被劃分為扇區(qū);第三級(jí):從塊序列到三個(gè)區(qū)域的劃分。在linux下,磁盤被劃分為三個(gè)區(qū)域:超級(jí)塊,i-結(jié)點(diǎn)和書局區(qū)。超級(jí)塊
是文件系統(tǒng)的第一個(gè)塊,存放文件系統(tǒng)本身的信息,i-結(jié)點(diǎn)存放每個(gè)文件的屬性『大小,文件所有者,權(quán)限等』。數(shù)據(jù)區(qū)存放文件的內(nèi)容。
2、創(chuàng)建一個(gè)文件的過(guò)程
??? 四個(gè)步驟:
— 存儲(chǔ)屬性,分配i-結(jié)點(diǎn);
??? — 存儲(chǔ)數(shù)據(jù),維護(hù)一個(gè)存放文件的塊列表;
??? — 記錄分配情況,在i-結(jié)點(diǎn)的磁盤分布區(qū)記錄了存放文件的塊序列;
??? — 添加文件名到目錄,在目錄文件中增加一條記錄。
3、目錄的工作過(guò)程
??? 目錄是包含了文件名子列表的特殊文件,可以使用命令ls -1ia
director來(lái)查看對(duì)應(yīng)的i-node號(hào)。理解目錄和目錄的工作過(guò)程是理解文件系統(tǒng)的關(guān)鍵。在每個(gè)目錄文件的列表中有兩個(gè)特殊的項(xiàng):.代表本級(jí)目
錄,..代表上級(jí)目錄,并且都有對(duì)應(yīng)的i-node號(hào),所以我們可以通過(guò)這兩個(gè)i-node號(hào)逐級(jí)向上就可以找到當(dāng)前工作目錄的絕對(duì)路徑。但是什么時(shí)間算
到了根目錄呢?先執(zhí)行l(wèi)s -i /看看結(jié)果,可以發(fā)現(xiàn),根目錄下的.和..對(duì)應(yīng)的i-node號(hào)相同,這可以作為搜索結(jié)束的條件。
4、pwd命令的實(shí)現(xiàn)
代碼如下:
?1?/*
?2??*?starts?in?current?directory?and?recursively?climbs?up?to?root
?3??*?of?filesystem,?prints?top?part?then?prints?current?part
?4??*?use?readdir()?to?get?info?about?each?thing
?5??*/
?6??
?7??#include?<stdio.h>
?8??#include?<sys/types.h>
?9??#include?<sys/stat.h>
10??#include?<dirent.h>
11??#include?<stdlib.h>
12??#include?<string.h>
13??#include?<unistd.h>
14??
15??ino_t?get_inode(char?*);
16??void?printpathto(ino_t);
17??void?inum_to_name(ino_t,?char?*,?int);
18??
19??int?main()
20??{
21????printpathto(get_inode("."));
22????printf("\n");
23????return?0;
24??}
25??
26??void?printpathto(ino_t?this_inode)
27??/*
28???*?prints?path?leading?down?to?an?object?with?this?inode
29???*?kind?of?recursive
30???*/
31??{
32????ino_t?my_inode;
33????char?its_name[BUFSIZ];
34????if(get_inode("..")?!=?this_inode)??????//not?lead?to?root
35????{
36??????chdir("..");????????????????????????????????//up?one?dir
37??????inum_to_name(this_inode,?its_name,?BUFSIZ);?//get?its?name
38??????my_inode?=?get_inode(".");
39??????printpathto(my_inode);
40??????printf("/%s",?its_name);
41????}
42??}
43??
44??void?inum_to_name(ino_t?inode_to_find,?char?*namebuf,?int?buflen)
45??/*
46???*looks?through?current?directory?for?a?file?with?this?node
47???*number?and?copies?its?name?into?namebuf
48???*/
49??{
50????DIR?*dir_ptr;
51????struct?dirent?*direntp;
52????dir_ptr?=?opendir(".");
53????if(dir_ptr?==?NULL)
54????{
55??????perror(".");
56??????exit(1);
57????}
58????while((direntp?=?readdir(dir_ptr))?!=?NULL)
59????{
60??????if?(direntp->d_ino?==?inode_to_find)
61??????{
62????????strncpy(namebuf,?direntp->d_name,?buflen);
63????????namebuf[buflen?-?1]?=?'\0';
64????????closedir(dir_ptr);
65????????return?;
66??????}
67????}
68????fprintf(stderr,?"error?looking?for?inum?%d\n",?inode_to_find);
69????exit(1);
70??}
71??
72??
73??ino_t?get_inode(char?*fname)
74??{
75????/*
76?????*?return?inode?number?of?the?file
77?????*/
78?????struct?stat?info;
79?????if((stat(fname,?&info))?==?-1)
80?????{
81???????fprintf(stderr,?"Cannot?stat");
82???????perror(fname);
83???????exit(1);
84?????}
85?????
86?????return?info.st_ino;
87??}
88??
89?
結(jié)論:
對(duì)于理解系統(tǒng)編程,理解操作系統(tǒng),學(xué)習(xí)相關(guān)的命令,并探究命令的實(shí)現(xiàn)過(guò)程,最后自給編寫一個(gè)同樣功能的命令,不失為一種很好的學(xué)習(xí)方法。