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


    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

     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
    ", get_inode( "." ) );
    24     printf( "上层目录..的inode=%ld
    ", 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打开失败
    ", name );
    33         exit( -1 );
    34     }
    35     return statinfo.st_ino;
    36 }
    View Code

    2,完整的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
    ", get_inode( "." ) );
    33     //printf( "上层目录..的inode=%ld
    ", get_inode( ".." ) );
    34     printpathto( get_inode( "." ) );
    35     putchar( '
    ' );
    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
    " );
    61         exit( -1 );
    62     }
    63     //printf( "cur inode=%ld
    ", cur_node );
    64     while( ( pCurDir = readdir( dir_entry ) ) != NULL  ) {
    65         if( cur_node == pCurDir->d_ino ) {
    66             //printf( "%s
    ", pCurDir->d_name );
    67             strncpy( str, pCurDir->d_name, bufsize );
    68             str[bufsize-1] = '';
    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打开失败
    ", 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组成级联关系

  • 相关阅读:
    dp的小理解
    POJ
    isolate-user-vlan隔离用户vlan的配置
    【mvrp多协议vlan注册协议给予三种注册方式的验证】
    【Commare中关于理论范畴和技术常用的技术术语】
    BGP映射和联盟
    filter-policy和AS-PATH-FILTER过滤BGP路由条目
    【路由过滤工具小结】
    【ISIS(中间系统到中间系统)路由链路状态信息协议初识】
    【poe设备加电配置】
  • 原文地址:https://www.cnblogs.com/ghostwu/p/8256942.html
Copyright © 2020-2023  润新知