zoukankan      html  css  js  c++  java
  • 20155219--pwd指令的简单实现

    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
      image
      通过上面提供的函数,返回一个结构体,保存着文件的信息。

    这一个结构体的成员表示,文件的索引信息(进入点),“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)] = '';  
                closedir(dir_ptr);  
                return ;  
            }  
        }  
        fprintf(stderr, "error looking for inode number %d
    ", (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字符数组中,准备输出打印

    具体代码

    实现效果如下图

  • 相关阅读:
    HDU 5583 Kingdom of Black and White 水题
    HDU 5578 Friendship of Frog 水题
    Codeforces Round #190 (Div. 2) E. Ciel the Commander 点分治
    hdu 5594 ZYB's Prime 最大流
    hdu 5593 ZYB's Tree 树形dp
    hdu 5592 ZYB's Game 树状数组
    hdu 5591 ZYB's Game 博弈论
    HDU 5590 ZYB's Biology 水题
    cdoj 1256 昊昊爱运动 预处理/前缀和
    cdoj 1255 斓少摘苹果 贪心
  • 原文地址:https://www.cnblogs.com/paypay/p/7860361.html
Copyright © 2011-2022 走看看