zoukankan      html  css  js  c++  java
  • C语言实现Linux之ls

    ls命令用来显示目标列表。

     

    常用参数:

    -l    :以长格式显示目录下的内容列表。输出信息从左向右依次包括文件名,文件类型,权限模式,硬连接数,所有者、组、文件大小和文件的最后修改时间等;

    -a   :显示所有档案及目录;

    -r    :以文件名反序排列并输出目录内容列表;

    -t    :用文件和目录的更改时间排序;

    -R   :递归处理,将指定目录下的所有文件及子目录一并处理。

    常用参数组合:

    ls –rtl:反向按时间排序,查看一个目录下最近修改的文件。

    ls –full-time:在写shell脚本的时候需要获取文件被更新的时间,此命令可以获取时间细微的变化。

    获取指定目录下文件名:

    /*
    ls_name.c
    */
    #include<stdio.h>
    #include<sys/types.h>
    #include<dirent.h>
    
    void do_ls(char[]);
    
    int main(int argc, char **argv)
    {
        if (argc == 1)
        {
            do_ls(".");
        }
        else
        {
            while(--argc)
            {
                printf("%s:
    ",*++argv);
                do_ls(*argv);
            }
        }
    
        return 0;
    }
    
    
    void do_ls(char dirname[])
    {
        DIR* dir_ptr;
        struct dirent *direntp;
    
        if ((dir_ptr = opendir(dirname)) == NULL)
        {
            fprintf(stderr, "ls1: cannot open %s
    ",dirname);
        }
        else
        {
            while((direntp = readdir(dir_ptr)) != NULL) 
            {
                //printf("direntp->d_name = %s
    ",direntp->d_name);
                if(    strcmp(direntp->d_name, ".") != 0 &&
                    strcmp(direntp->d_name, "..") != 0)
                printf("%s
    ", direntp->d_name);
            }
            close(dir_ptr);
        }
    }

    运行结果:

    获取指定文件详细信息:

    /*
    ls_fileinfo.c
    */
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    
    void show_stat_info(char *filename, struct stat *buf)
    {
        printf("mode		:%o
    ", buf->st_mode);
        printf("linkers		:%d
    ",(int)buf->st_nlink);
        printf("user		:%d
    ", buf->st_uid);
        printf("group_id	:%d
    ", buf->st_gid);
        printf("size		:%d
    ", (int)buf->st_size);
        printf("modtime		:%d
    ", (int)buf->st_mtime);
        printf("group_name	:%s
    ", filename);
    }
    
    int main(int argc, char **argv)
    {
        struct stat info;
    
        if (argc > 1)
        {
            if (stat(argv[1], &info) != -1)
            {
                show_stat_info(argv[1], &info);
            }
            else
            {
                perror(argv[1]);
            }
        }
    
        return 0;
    }

    运行结果:

    Linux下对于不同用户的权限展示,分别是用户、用户组、所在组在stat结构体中的mode这个字段进行存储。

    mode字符是一个16位的二进制数,前4位用作文件类型,1代表具有某个属性,0代表没有。

    接下来的三位分别为user-ID,set-group-ID和sticky位,最后9位是许可权限,分三组,每组3位。

    这里使用掩码的技术来划分,就跟ip中的子网掩码一样把2进制的1000000110110110划分为1,000,000,110,110,110,从而得到8进制的100664

    对二进制进行位与操作,就是所谓的解码。例如判断目录的代码如下:

    if ((info.st_mode & 0170000) == 0040000)
    {
        printf(“this is a directory”);
    }

    用宏定义代替以上代码:

    #define S_ISFIFO(m)  (((m)&(0170000))==(0040000))
    #define S_ISDIR(m)  (((m)&(0170000))==(0020000))
    #define S_ISCHR(m)  (((m)&(0170000))==(0060000))
    #define S_ISBLK(m)  (((m)&(0170000))==(0100000))
    if(S_ISDIR(info.st_mode))
    {
        printf("this is a directory");
    }

    获取指定目录下详细文件信息

    /*
    ls_fin.c
    */
    #include<stdio.h>
    #include<string.h>
    #include<sys/types.h>
    #include<dirent.h>
    #include<sys/stat.h>
    #include<grp.h>
    #include<pwd.h>
    
    void do_ls(char []);
    void dostat(char *);
    void show_file_info(char *, struct stat *);
    void mode_to_letters(int mode, char str[]);
    char *uid_to_name(uid_t uid);
    char *gid_to_name(gid_t gid);
    
    
    int main(int argc, char **argv)
    {
        if (argc == 1)
        {
            do_ls(".");
        }    
        else
        {
            while (--argc)
            {
                printf("%s:
    ", *++argv);
                do_ls(*argv);
            }
        }
    
        return 0;
    }
    
    void do_ls(char dirname[])
    {
        DIR *dir_ptr;
        struct dirent *direntp;
    
        if ((dir_ptr = opendir(dirname)) == NULL)
        {
            fprintf(stderr, "ls2: cannot open %s
    ", dirname);
        }
        else
        {
            while((direntp = readdir(dir_ptr)) != NULL)
            {
                dostat(direntp->d_name);
            }
            closedir(dir_ptr);
        }
    }
    
    void dostat(char *filename)
    {
        struct stat info;
        if (stat(filename, &info) == -1)
        {
            perror(filename);
        }
        else
        {
            show_file_info(filename, &info);
        }
    }
    
    void show_file_info(char *filename, struct stat *info_p)
    {
        char *uid_to_name(), *ctime(), *gid_to_name();
        void mode_to_letters();
        char modestr[11];
    
        mode_to_letters(info_p->st_mode, modestr);
    
        printf("%s",modestr);
        printf("%4d ",(int)info_p->st_nlink);
        printf("%-8s ", uid_to_name(info_p->st_uid));
        printf("%-8s ", gid_to_name(info_p->st_gid));
        printf("%8ld ", (long)info_p->st_size);
        printf("%.12s ", 4 + ctime(&info_p->st_mtime));
        printf("%s
    ", filename);
    }
    
    void mode_to_letters(int mode, char str[])
    {
        strcpy(str, "-----------");
    
        if (S_ISDIR(mode))    str[0] = 'd';
        if (S_ISCHR(mode))    str[0] = 'c';
        if (S_ISBLK(mode))    str[0] = 'b';
    
        if (mode & S_IRUSR)    str[1] = 'r';
        if (mode & S_IWUSR) str[2] = 'w';
        if (mode & S_IXUSR)    str[3] = 'x';
    
        if (mode & S_IRGRP)    str[4] = 'r';
        if (mode & S_IWGRP)    str[5] = 'w';
        if (mode & S_IXGRP) str[6] = 'x';
    
        if (mode & S_IROTH) str[7] = 'r';
        if (mode & S_IWOTH)    str[8] = 'w';
        if (mode & S_IXOTH)    str[9] = 'x';
    }
    
    char *uid_to_name(uid_t uid)
    {
        struct passwd * getpwuid(), *pw_ptr;
        static char numstr[10];
    
        if ((pw_ptr = getpwuid(uid)) == NULL)
        {
            sprintf(numstr, "%d", uid);
            return numstr;
        }
        else
        {
            return pw_ptr->pw_name;
        }
    }
    
    char *gid_to_name(gid_t gid)
    {
        struct group *getgrgid(), *grp_ptr;
        static char numstr[10];
    
        if ((grp_ptr = getgrgid(gid)) == NULL)
        {
            sprintf(numstr, "%d", gid);
            return numstr;
        }
        else
        {
            return grp_ptr->gr_name;
        }
    }

    运行结果:

  • 相关阅读:
    javascript 基础知识-1
    AngularJs-指令和指令之间的交互(动感超人)
    AngularJs-指令和控制器交互
    奇点大学公开课之尼葛洛庞帝讲述物联网和智能设备
    AngularJs-数据绑定
    AngularJs-指令1
    AngularJs-MVC之路由、模块以及依赖注入
    AngularJS-MVC
    利用canvas制作图片(可缩放和平移)+相框+文字
    Django rest framework 认证组件源码分析
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11959330.html
Copyright © 2011-2022 走看看