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


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组成级联关系

相关内容

    暂无相关文章