20165203 Mypwd的解读与实现
pwd
- 含义:在Linux层次结构中,想要知道当前所处的目录,可以用pwd命令,该命令显示整个路径名。
- 语法:
pwd [option]
- 描述:pwd 命令将当前目录的全路径名称(从根目录)写入并进行标准输出。全部目录使用 /(斜线)分隔。第一个 / 表示根目录,最后一个目录是当前目录。
- 参数:
-L | 使用环境中的路径(包含符号链接) |
-P | 避免了所有的符号链接 |
-help | 显示帮助信息 |
-version | 输出帮助信息 |
- 用法:通常用于查看当前工作目录的完整性
- 退出状态:
0 | 成功 |
非0值 | 失败 |
实现过程
- 思路:通过整个系统文件组织是树形的这个特点,pwd以绝对路径打印当前的工作目录。我们可以从当前目录逐层向根目录进行查找,当找到根目录,即可得到完全路径。
- 那么,问题来了,如何进行逐层查找呢?
- 原来,整个系统通过一种
inode节点
来管理文件,所以,每个文件都有一个inode号
。我们知道,目录是比较特殊的文件,系统通过<inode,name>
的列表组织目录下的文件,而每个目录下有两个特殊的文件名---.
(当前目录)和..
(父目录)。 - 又有了一个问题,如何知道我们已经到了根目录了?
- 到达根目录自然就没有父目录,但是两个特殊的文件名
.
和..
仍然存在于根目录中,但他们表达的是都是当前目录文件,自然inode号
是相同的。 - 还有一个很重要的问题,怎么得到完整的路径呢?
- 查看系统所有的挂载路径,将所有挂载路径和上面求得的路径拼接起来,如果是合法路径且inode号与最初目录的inode号相同,即是想要的最终的路径。
查找函数
使用
man -k directory | grep 3
命令查找与路径有关的库函数,可以发现opendir
、readdir
和getcwd
。通过
man 3 readdir
查找到相应结构体通过
man -k inode
发现有stat
函数找到
readlink
的帮助文档
编写代码
#include<stdio.h>
#include<sys/stat.h>
#include<dirent.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
//获得文件的inode号
int getinode(char *str)
{
struct stat st;
if(stat(str,&st) == -1){
perror(str);
exit(-1);
}
return st.st_ino;
}
//找到对应的文件名
char *inode_to_name(int inode)
{
char *str;
DIR *dirp;
struct dirent *dirt;
if((dirp = opendir(".")) == NULL){
perror(".");
exit(-1);
}
while((dirt = readdir(dirp)) != NULL)
{
if(dirt->d_ino == inode){
str = (char *)malloc(strlen(dirt->d_name)*sizeof(char));
strcpy(str,dirt->d_name);
return str;
}
}
perror(".");
exit(-1);
}
//输出路径
void printpath()
{
int inode,up_inode;
char *str;
inode = getinode(".");
up_inode = getinode("..");
chdir("..");
str = inode_to_name(inode);
if(inode == up_inode) {
// printf("/%s",str);
return;
}
printpath();
printf("/%s",str);
}
int main()
{
printpath();
putchar('\n');
return ;
}
测试结果
感想
本次用C语言实现了pwd的命令,其实,我学到更多的是man
命令的用法和系统管理文件的方式,希望自己还可以总结一下man
的用法。