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

时间:2022-03-31 22:27:05

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

linux系统编程:自己动手写一个pwd命令linux系统编程:自己动手写一个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
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源码

linux系统编程:自己动手写一个pwd命令linux系统编程:自己动手写一个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组成级联关系