linux系统编程:自己动手写一个pwd命令

pwd命令:打印当前的工作目录

我们都知道每个目录下面都有两个特殊的目录( . 和 .. ), .: 当前目录, ..: 上层目录,  每个目录都有一个i节点与之相关联

ghostwu@ubuntu:~$ ls -i
3677860 bak        3670018 examples.desktop     1507 python
3678042 core       3670033 Music                1506 shell_script
   1505 c_program  3672560 note              3670169 software
3672551 data       3675147 php               3678095 tags
3670028 Desktop     150874 php_study         3670030 Templates
3670032 Documents  3670034 Pictures          3677997 unix
3670029 Downloads  3670031 Public            3670035 Videos

通过ls -i就可以显示每个文件和目录的inode值,比如下面我用ls -ia显示所有文件的inode

1,当工作在basic目录下面的时候,   当前目录basic( 也就是. )他的inode值为1573909,   ..: 1507

2,当把路径切换到python时候, .: 1507 刚好就跟basic的 .. 相等。后面依次类推

通过inode的关联就把目录的层级关系给找出来了,下一个问题:如何知道,已经到达根目录?

ghostwu@ubuntu:~/python/basic$ ls -ia
1573909 .            8913 person2.class.py       8405 test1.py
   1507 ..           3427 person3.class.py       8897 test2.py
   8910 func2.py     8916 person4.class.py       4537 test3.py
   8911 func3.py     8912 person.class.py        8908 test4.py
   8909 func.py      8915 superlist.class.py
ghostwu@ubuntu:~/python/basic$ cd ..
ghostwu@ubuntu:~/python$ ls -ia
   1507 .  3670017 ..  1573911 advance  1573909 basic   151172 django
ghostwu@ubuntu:~/python$ cd ..
ghostwu@ubuntu:~$ ls -ia
3670017 .                 3672499 .mysql_history
      2 ..                3677054 .navicat64
   3695 .adobe            3672560 note
1050432 .atom             3675147 php
...

在根目录(/)下面的. 和 ..,他们的inode节点有个特点, 都是相等的,所以只要判断当前目录的inode等于上层目录的inode,就可以断定,到达根目录了

ghostwu@ubuntu:/$ ls -1ia
      2 .
      2 ..
 915713 bin
      2 boot
 130818 cdrom
      3 dev
 523265 etc
      2 home
     ...

1,第一个要解决的问题: 如果通过路径/文件名,得到对应的inode值,通过stat函数,获得文件/目录的struct stat结构体,文件信息都在这里保存,包括inode

 1 /*================================================================
 2 *   Copyright (C) 2018 . All rights reserved.
 3 *   
 4 *   文件名称:pwd.c
 5 *   创 建 者:ghostwu(吴华)
 6 *   创建日期:2018年01月10日
 7 *   描    述:pwd命令编写
 8 *
 9 ================================================================*/
10 
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15 #include <stdlib.h>
16 
17 
18 //读取当前文件的i节点
19 ino_t get_inode( char* name );
20 
21 int main(int argc, char *argv[])
22 {
23     printf( "当前目录.的inode=%ld\n", get_inode( "." ) );
24     printf( "上层目录..的inode=%ld\n", get_inode( ".." ) );
25     return 0;
26 }
27 
28 
29 ino_t get_inode( char* name ) {
30     struct stat statinfo;
31     if( -1 == stat( name, &statinfo ) ) {
32         printf( "文件%s打开失败\n", name );
33         exit( -1 );
34     }
35     return statinfo.st_ino;
36 }
View Code

2,完整的pwd源码

 1 /*================================================================
 2 *   Copyright (C) 2018 . All rights reserved.
 3 *   
 4 *   文件名称:pwd.c
 5 *   创 建 者:ghostwu(吴华)
 6 *   创建日期:2018年01月10日
 7 *   描    述:pwd命令编写
 8 *
 9 ================================================================*/
10 
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include <dirent.h>
17 #include <string.h>
18 
19 #ifndef BUFSIZE
20 #define BUFSIZE 100
21 #endif
22 
23 
24 //读取当前文件的i节点
25 ino_t get_inode( char* name );
26 void printpathto( ino_t cur_node );
27 //根据当前inode节点,找到它对应的路径名称
28 void inode_to_name( ino_t cur_node, char* str, int bufsize );
29 
30 int main(int argc, char *argv[])
31 {
32     //printf( "当前目录.的inode=%ld\n", get_inode( "." ) );
33     //printf( "上层目录..的inode=%ld\n", get_inode( ".." ) );
34     printpathto( get_inode( "." ) );
35     putchar( '\n' );
36     return 0;
37 }
38 
39 void printpathto( ino_t cur_node ) {
40 
41     char dir_name[BUFSIZE];
42     ino_t my_node;
43     //如果当前节点不等于..,说明没有到达根目录
44     if( cur_node != get_inode( ".." ) ) {
45         //切换到上层目录, 当前目录(.)的名称在上层目录(..)
46         //所以找名称之前,先要切换到上层目录
47         chdir( ".." );
48         inode_to_name( cur_node, dir_name, BUFSIZE );
49         //chdir( ".." ); //不能放在这里,放在这里 找不到目录的名称
50         my_node = get_inode( "." );
51         printpathto( my_node );
52         printf( "/%s", dir_name );
53     }
54 }
55 
56 void inode_to_name( ino_t cur_node, char* str, int bufsize ) {
57     DIR* dir_entry;
58     struct dirent* pCurDir;
59     if( ( dir_entry = opendir( "." ) ) == NULL ) {
60         printf( "open cur directory error\n" );
61         exit( -1 );
62     }
63     //printf( "cur inode=%ld\n", cur_node );
64     while( ( pCurDir = readdir( dir_entry ) ) != NULL  ) {
65         if( cur_node == pCurDir->d_ino ) {
66             //printf( "%s\n", pCurDir->d_name );
67             strncpy( str, pCurDir->d_name, bufsize );
68             str[bufsize-1] = '\0';
69             closedir( dir_entry );
70             return;
71         }
72     }
73 }
74     
75 
76 ino_t get_inode( char* name ) {
77     struct stat statinfo;
78     if( -1 == stat( name, &statinfo ) ) {
79         printf( "文件%s打开失败\n", name );
80         exit( -1 );
81     }
82     return statinfo.st_ino;
83 }
View Code

运行之后的效果:

ghostwu@ubuntu:~/c_program/linux_unix/chapter4$ ./pwd
/ghostwu/c_program/linux_unix/chapter4

还少了一层home,在home这层停止了

ghostwu@ubuntu:/home$ ls -ia
      2 .        2 ..  3670017 ghostwu       11 lost+found

home这层确实是 . 和 ..相等? 为什么会有这样的情况? 因为/home这个是一个分区,在linux中,每个分区都有独立的根目录结构,  /home就是这个分区的根节点,只不过被挂载到根分区( / )下面

总结:

1)linux文件分区与结构

2)目录和文件通过inode组成级联关系

posted @ 2018-01-10 11:00 ghostwu 阅读(...) 评论(...) 编辑 收藏
Copyright ©2017 ghostwu