pwd指令的简单实现

  • pwd命令作用

Linux中用** pwd **命令来查看”当前工作目录“的完整路径。 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录。

在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置。

1.命令格式:

pwd [选项]

2.命令功能:

查看”当前工作目录“的完整路径

3.常用参数:

一般情况下不带任何参数

如果目录是链接时:

格式:pwd -P 显示出实际路径,而非使用连接(link)路径。

首先通过man pwd查看pwd的详细用法,如下图:

知道了函数getcwd可能对于pwd命令的实现有所帮助,之后通过命令man getcwd查看此函数的具体用法

如下图:

知道了可以通过此函数来简单实现pwd命令。

可以采取令 buf 为 NULL并使 size 为零(百度百科里介绍可以使用负值但我测试的时候是段错误)来使 getcwd 调用 malloc 动态给 buf 分配,但是这种情况要特别注意使用后释放缓冲以防止内存泄漏。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(void)
{
char *path = NULL;
path = getcwd(NULL,0);
puts(path);
free(path);
return 0;
}
  • 通过命令man -k status|grep 2查找可用函数,如下图所示

老师在课堂给出提示使用stat函数

  • 1.stat函数讲解
stat函数讲解

表头文件:    #include <sys/stat.h>
#include <unistd.h>
定义函数: int stat(const char *file_name, struct stat *buf);
函数说明: 通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
返回值: 执行成功则返回0,失败返回-1,错误代码存于errno
  • 2 文件对应的属性

    通过man 2 stat查看函数stat



    通过上面提供的函数,返回一个结构体,保存着文件的信息。

这一个结构体的成员表示,文件的索引信息(进入点),“number”告诉我们它是一个数字表示,而不是一个确切的路径,这就好比我们有时候用文件描述符来操作文件,而不用字符数组(文件名)来操作。

也就是说,我们想要找到文件的路径,st_ino这个信息试关键。

具体思路:

计算机内核为每一个目录都设置了一个指向自己的i节点入口,即".",还有一个指向其父目录i节点的入口,即”..",我们可以使用cd . 或者cd .. 来回到当前目录下或者父目录下。我们首先获取当前目录的i节点编号,但是并不能知道当前目录的名称,我们切换到其的父目录,在里面寻找当前i节点编号对应的文件名即可。这样我们就很容易联想到使用递归来实现,但是终止条件是什么呢?在Unix文件系统的根目录中,“."和“..”指向同一个i节点,我们可以以此判断是否发到达了根目录。如下图所示:

伪代码如下:

while(“."和“..”不指向同一个i节点)
切换到当前的父目录,在里面寻找当前i节点编号对应的文件名
收集 最后打印字符数组
  • get_inode函数--使用stat函数来得到当前目录下的文件信息,主要是获得i-node信息。
ino_t get_inode(char *dirname)
{
struct stat a;
if (stat(dirname, &info) == -1)
{
perror("dirname");
exit(1);
} return a.st_ino;
}
  • 要读取路径,必定要先打开路径,路径如何打开可以用指令查询一下:man -k dir | grep open 得到函数opendir

    如下图

输入指令:man 3 opendir查看详细信息

输入参数为一个文件(目录)名,才能打开该目录,并且返回为DIR类型

我们已经知道目录名,当前目录的目录名为.,父级目录的目录名为..。

  • 如何将它的各个父目录读取出来呢?跟读取有关(read)

    用指令搜索查询一下:man -k dir | grep read

    如下图:

找到相关项后输入指令:man readdir

其中有d_ino和d_name[256],这两者应该是一一对应的,也就是说我只要取得了其索引号,就可以将其翻译为文件名了。

使用函数void inode_to_dirname(ino_t inode_num, char buf,int buflen) 来获得当前文件名,并添加到buf中

void inode_to_dirname(ino_t inode_num, char *buf,int buflen)
{
DIR *dir_ptr;
struct dirent *dire;
if ((dir_ptr = opendir(".")) == NULL)
{
perror(".");
exit(1);
} while ((dire = readdir(dir_ptr)) != NULL)
{
if (dire->d_ino == inode_num)
{
strncpy(buf, dire->d_name, buflen);
buf[strlen(buf)] = '\0';
closedir(dir_ptr);
return ;
}
}
fprintf(stderr, "error looking for inode number %d\n", (int)inode_num);
exit(1);
}

此函数是将索引节点转化为相应的文件名的过程,具体方法是将一个个读取的目录的ino信息与传参进来的ino信息做比对,如果相同,则说明找到了正确目录,把文件名拷贝到字符数组就行;如果比对结果不相同,则继续读取下一个目录。

void get_work_dir(ino_t inode_num)
{
ino_t parent_inode;
char buf[SIZE];
if (get_inode("..") != inode_num)
{
chdir("..");
inode_to_dirname(inode_num, buf, SIZE);
parent_inode = get_inode(".");
get_work_dir(parent_inode);
printf("/%s", buf);
}
}

此函数实现了递归调用,具体实现内容如下:

传入一个索引节点,并求得父目录的索引节点,判断两者是否相等,相等则说明已经到了根文件夹下,可以终止递归调用

如若不相等,则进入父目录,然后通过inum_to_name函数功能,将之前的目录名拷贝到its_name字符数组中,准备输出打印

具体代码

实现效果如下图

20155219--pwd指令的简单实现的更多相关文章

  1. 2017-2018-3 20155337《信息安全系统设计基础》 pwd指令学习

    2017-2018-3 20155337<信息安全系统设计基础> pwd指令学习 任务要求 学习pwd指令 研究pwd实现需要的系统调用(man -k:grep),写出伪代码 实现mypw ...

  2. linux pwd指令C实现

    linux pwd指令C实现 研究实现pwd所需的系统调用 我们可以通过man命令和grep命令来获取我们所需要的系统调用函数信息 man chdir Linux pwd命令用于显示工作目录. 执行p ...

  3. linux pwd指令的C实现

    linux pwd指令的C实现 pwd指令的功能介绍 linux pwd命令用于显示工作目录 执行pwd命令可立刻得知当前所在工作目录的绝对路径名称. 示例: 查询系统手册 如图所示,getcwd的描 ...

  4. angular指令的简单练习

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. v-model指令实现简单的问卷表格

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&q ...

  6. linux——通信指令学习简单笔记

    一: 指令名称:write 指令所在路径:/usr/bin/write 执行权限:All User 语法:write <用户名> 功能描述:向另外一个用户发信息,以Ctrl+D作 为结束 ...

  7. Linux指令--cd,pwd

    本文参照博客做了修改和总结,感谢作者的分享.http://www.cnblogs.com/peida/archive/2012/10/24/2736501.html cd 命令可以说是Linux中最基 ...

  8. --@angularJS--一个最简单的指令demo

    <!DOCTYPE HTML><html ng-app="app"><head>    <title>custom-directiv ...

  9. 指令——pwd

    完整的指令的标准格式:Linux通用的格式 #指令主体(空格) [选项](空格) [操作对象] 一个指令可以包含多个选项,操作对象也可以是多个. 指令pwd: 用法:#pwd(print workin ...

随机推荐

  1. nyoj-0469-擅长排列的小明 II(找规律)

    nyoj-0469-擅长排列的小明 II 思路:递推分析:为了简便起见,我们用Ai代表第i个数字 , 由于A1一直是1,所以A2只能是2或3.假设dp[n]表示1->n这个序列的方案数      ...

  2. learning ddr mode reigster set command cycle time tMRD and tMOD

    tMRD: tMOD:

  3. 利用FFMPEG命令进行文件分割

    ffmpeg -ss 00:00:00 -i input.mp4 -c copy -t 60 output.mp4 -ss 表示视频分割的起始时间,-t 表示分割时长,同时也可以用 00:01:00表 ...

  4. OOP⑺

    1.多态和instanceof 都是去买东西,但是根据我们给别人金额的不同,得到不同的结果!!!! 生活中的多态! 操作是否一致? 一致! 都是买东西! 什么不一样?? 01.消费金额不一样 02.因 ...

  5. CSS--margin塌陷

    margin塌陷 解决方法: 1.给父级顶加上一条线,不太合适. 2.bfc block format context 设定bfc后,特定的盒子会遵循另一套语法规则,解决了margin塌陷 触发bfc ...

  6. JXL生成Excel,并提供下载(2:提供下载)

    实现效果: 项目中使用JXL生成Excel,使生成的Excel可以让用户下载,如下图 一.生成Excel 二.提供下载 实现思路: 1.页面使用form表单提交方式(Ajax提交方式,我这里不行) 2 ...

  7. find 命令实战巧用

    一.命令简介 find 命令的 -size 参数 单位b(不是byte而是block).c.w.k.M.G.默认是单位b ,也就是1block = 512byte = 0.5kb (文件系统ext4) ...

  8. X86汇编语言实现的贪吃蛇游戏

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  9. HashMap实现原理分析--面试详谈

    1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1 ...

  10. 深入理解java虚拟机---java虚拟机的发展史(四)

    1.java虚拟机 A:java虚拟机有很多个版本,但是我们经常使用的是sun公司的HotSpot,可以通过以下命令获取java虚拟机版本 B:JAVA虚拟机分类: 1.Sun Class VM 2. ...