pwd 命令实现

最近Linux课要考试了,在复习文件系统。顺便就尝试实现一下pwd命令

这个命令的功能很简单,就是显示当前目录的绝对路径


key point:


由于在Linux/Unix文件系统中,每个文件对应的inode值都是唯一的。这个就是我们要寻找的突破点。



算法核心:


1. 拿到当前目录中"."这个目录的st_ino值,记为inode。

2. 转到父目录中,遍历父目录,找到第一个st_ino值与inode相同的那个目录,并保存名字。

3. 再拿当前目录中"."目录的st_ino值作为inode,向前递归(此时的"."目录已经不是1中的"."了,而是1中的"..")

4. 输出 “/" + 2中保存的名字


由于3与4之间的次序关系,保证了输出的字符串中,子目录总是在父目录后面的。



递归出口:


由于在根目录下,"." 和 ".." 的inode值是一样的,所以当递归到某一层,若父目录的inode值与当前的inode值(作为递归函数的参数传入) 相同,那么就可以结束递归了。



注意:


需要注意的就是,步骤2 要把遍历父目录的那个函数的当前路径跳转到父目录中去,chdir("..")。如果不这样子做的话,你匹配到的那个字符串始终是 ".",且你的目标的st_ino和inode不一样 !!!  结果,程序的输出就变成这样了:/./././. ....  读者可以自行尝试。下面是我在/Users/user下的一个测试程序的输出:


 程序分别输出:

1. 当前目录下,"."的st_ino值

2. 父目录下所有文件的st_ino值,(其中"user" 是正确的目标目录名)

(如果"."和"user"的inode值相同,那么才算正确)


1. 没有加chdir,仅以opendir("..")代替,出错!!! 



2. 加上chdir(".."),转换到父目录后,应该 opendir(".") 而不是 opendir("..")了,正确!!!

    看,当前目录中,"."的inode值是603090,父目录中,"user"的inode值也是603090






源代码:


#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

int flag = 0;

unsigned long get_inode(char *name) {
	struct stat e;
	if (lstat(name,&e) == -1) {
		printf("lstat error\n");
		return 0;
	}
	return e.st_ino;
}

void pwd(unsigned long inode) {
	struct dirent *dp;
	struct stat e;
	DIR* dir;

	if(get_inode("..") == inode)
		return;

	chdir("..");
	if((dir = opendir(".")) == NULL) {
		printf("opendir error\n");
		return;
	}	
	while ( (dp = readdir(dir)) != NULL) {
		if (lstat(dp->d_name,&e) == -1) {
			printf("lstat error\n");
			break;	
		}
		if (e.st_ino == inode) {
			flag = 1;
			pwd(get_inode("."));
			printf("/%s",dp->d_name);
			break;
		}
	}
	closedir(dir);
}

int main(int args , char * argv[]) {
	pwd(get_inode("."));
	if(!flag) printf("/");	
	printf("\n");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值