du命令的简单实现

  • Post author:
  • Post category:其他




标题会用到的一些相关函数



du

man du:
Summarize disk usage of the set of FILEs, recursively 
for directories

作用:看当前文件或目录所占空间的大小(k数)

stat ctags
  文件:ctags
  大小:4096            块:8          IO 块:4096   目录
设备:10308h/66312d     Inode:6294771     硬链接:2
权限:(0755/drwxr-xr-x)  Uid:( 1000/erfenjiao)   Gid:( 1000/erfenjiao)
最近访问:2021-08-02 08:40:17.612516404 +0800
最近更改:2021-03-19 21:18:33.016832426 +0800
最近改动:2021-03-19 21:18:33.016832426 +0800
创建时间:-


du ctags
8       ctags



strchr

man strchr

#include <string.h>

char *strchr(const char *s, int c);

char *strrchr(const char *s, int c);
在s字符串中,找出c的内容,获取最右面那个c



代码

/*************************************************************************
	> File Name: du.c
	> Author: erfenjiao 
	> Mail: 630166475@qq.com 
	> Created Time: 2021年08月02日 星期一 15时01分03秒
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<glob.h>

#define PATHSIZE  1024

static int path_noloop(const char * path)
{
    char * pos;

    pos = strrchr(path , '/');
    if(pos == NULL)
    {
        exit(1);
    }
    if(strcmp(pos+1 , ".") == 0 || strcmp(pos+1 , "..") == 0)
    {
        return 0;
    }
    return 1;

}

static int64_t mydu(const char *path)
{
    /**
    * path 
    *      是目录文件   /*本目录下 
    *                  /.*下一级
    *      是非目录文件 return st_blocks
    */
    struct stat statres;
    char nextpath[PATHSIZE];
    glob_t globres;
    if(lstat(path , &statres) < 0)
    {
        perror("lstat");
        exit(1);
    }
    //printf("ssssss");
    if(!S_ISDIR(statres.st_mode))   //非目录文件
    {
        return statres.st_blocks;
    }
    strcpy(nextpath , path);
    strcat(nextpath , "/*" );
    glob(nextpath , 0 , NULL , &globres);

    strcpy(nextpath , path);
    strcat(nextpath , "/.*");
    glob(nextpath , GLOB_APPEND , NULL , &globres);

    int64_t sum = statres.st_blocks;     //在递归点之前

    for(int i = 0 ; i < globres.gl_pathc ; i++)
    {
        if(path_noloop(globres.gl_pathv[i]))    //文件系统不是典型的树状结构,会有回路,譬如只有当前解析出来的不是 .  ..调用此函数,避免死循环
            sum += mydu(globres.gl_pathv[i]);
    }
    //sum += statres.st_blocks;  在递归点前加优化程序
    return sum;
}


int main(int argc , char ** argv)
{
    if(argc < 2)
    {
        fprintf(stderr , "Usage...\n");
        exit(1);
    }
    printf("%d\n",mydu(argv[1])/2);

}

结果展示

du ./                 //du命令
36      ./posix
632     ./第一阶段
696     ./
./du ./            //my_du
696



版权声明:本文为Daisy_G_Jasmine原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。