Linux下c实现ls
2022/1/17 7:07:20
本文主要是介绍Linux下c实现ls,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
主要功能及实现:
1,使用命令行参数分析,暂时只支持 -l -a -n ,可混合使用或不使用
2,对于隐藏文件目前只考虑 . 和 ..
源代码如下:
/************************************************************** > File Name: myls.c > Author: LuoLiang > Mail: 1204553475@qq.com > Created Time: 2022年01月08日 星期六 13时09分11秒 **************************************************************/ #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include <pwd.h> #include <grp.h> #include <glob.h> #include <time.h> #define SIZE 1024 /* 获取文件类型 */ static char getFileType(struct stat *statbuf) { switch (statbuf->st_mode & S_IFMT) { case S_IFREG: return '-'; case S_IFDIR: return 'd'; case S_IFSOCK: return 's'; case S_IFBLK: return 'b'; case S_IFIFO: return 'F'; default: return '?'; } } /* 获取权限信息 */ static char *getPermission(struct stat *statbuf) { char *buf; int i, k = 0; buf = calloc(9,sizeof(char)); if (buf == NULL) { fprintf(stderr,"calloc() fail\n"); exit(1); } for (i = 0; i < 9; i++) buf[i] = '-'; if (statbuf->st_mode & S_IRUSR) buf[k] = 'r'; if (statbuf->st_mode & S_IWUSR) buf[k+1] = 'w'; if (statbuf->st_mode & S_IXUSR) buf[k+2] = 'x'; if (statbuf->st_mode & S_IRGRP) buf[k+3] = 'r'; if (statbuf->st_mode & S_IWGRP) buf[k+4] = 'w'; if (statbuf->st_mode & S_IXGRP) buf[k+5] = 'x'; if (statbuf->st_mode & S_IROTH) buf[k+6] = 'r'; if (statbuf->st_mode & S_IWOTH) buf[k+7] = 'w'; if (statbuf->st_mode & S_IXOTH) buf[k+8] = 'x'; return buf; } /* 获取uname */ static char *getUsrname(int uid) { struct passwd *uid_line; uid_line = getpwuid(uid); if (uid_line == NULL) { perror("getpwuid()"); exit(1); } return uid_line->pw_name; } /* 获取gname */ static char *get_Gropname(int gid) { struct group *gid_line; gid_line = getgrgid(gid); if (gid_line == NULL) { perror("getpwuid()"); exit(1); } return gid_line->gr_name; } /* 获取文件去掉绝对路径的名字 */ static char *getRealName(char *pathname) { char *pos = NULL; pos = strrchr(pathname,'/'); if (pos) return pos+1; return pathname; } /* static int Judge_loop(char *pathname) { char *pos = NULL; pos = strrchr(pathname,'/'); if (strcmp(pos+1,".") == 0 || strcmp(pos+1,"..") == 0) return 0; return 1; } */ /* 根据参数打印文件属性 */ static void PrintFileNature(char *pathname,char *optbuf,struct stat *statbuf) { char *pms_ret = NULL; char *uid_ret = NULL; char *gid_ret = NULL; char *newname = NULL; char type; /* 将mtime改为本地时间 */ struct tm *t = localtime(&statbuf->st_mtime); pms_ret = getPermission(statbuf); newname = getRealName(pathname); type = getFileType(statbuf); if (optbuf[0] == 'l' && optbuf[2] != 'n') { uid_ret = getUsrname(statbuf->st_uid); gid_ret = get_Gropname(statbuf->st_gid); printf("%c%s %2ld %-4s %-4s %6ld %-2d月 %-2d %2d:%2d %-s\n",type,pms_ret,statbuf->st_nlink,uid_ret,gid_ret,\ statbuf->st_size,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,newname); } if (optbuf[1] == 'a' && optbuf[0] != 'l' && optbuf[2] != 'n') { puts(newname); } if (optbuf[2] == 'n') { printf("%c%s %2ld %-4d %-4d %-6ld %-2d月 %-2d %2d:%2d %-s\n",type,pms_ret,statbuf->st_nlink,statbuf->st_uid,\ statbuf->st_gid,statbuf->st_size,(t->tm_mon)+1,t->tm_mday,t->tm_hour,t->tm_min,newname); } if (optbuf[0] == 0 && optbuf[1] == 0 && optbuf[2] == 0) printf("%s\n",newname); } /* 获取文件夹里面文件的信息 */ static void getDirMsg(char *pathname,char *optbuf) { int l_ret; struct stat statbuf; l_ret = lstat(pathname,&statbuf); if (l_ret < 0) { perror("lstat()"); exit(1); } PrintFileNature(pathname,optbuf,&statbuf); } /* 通过文件类型进行对应操作 */ static void key_ls(char *pathname,char *optbuf) { int l_ret; struct stat statbuf; char pattern[SIZE] = {0}; glob_t line; l_ret = lstat(pathname,&statbuf); if (l_ret < 0) { perror("lstat()"); exit(1); } /* 如果是文件,直接打印属性信息 */ if (S_ISREG(statbuf.st_mode)) { PrintFileNature(pathname,optbuf,&statbuf); return ; } /* 如果是文件夹,获取文件夹下的文件 */ if(S_ISDIR(statbuf.st_mode)) { /* 文件隐藏文件匹配 */ if (optbuf[1] == 'a') { strncpy(pattern,pathname,SIZE); strncat(pattern,"/.",SIZE-1); glob(pattern,0,NULL,&line); strncpy(pattern,pathname,SIZE); strncat(pattern,"/..",SIZE-1); glob(pattern,GLOB_APPEND,NULL,&line); } strncpy(pattern,pathname,SIZE); strncat(pattern,"/*",SIZE-1); if (optbuf[1] == 'a') glob(pattern,GLOB_APPEND,NULL,&line); else glob(pattern,0,NULL,&line); for (int i = 0; i < line.gl_pathc; i++) { getDirMsg(line.gl_pathv[i],optbuf); } globfree(&line); } else return ; return ; } /* 根据文件名匹配 */ void func(char **pathname,char *optbuf) { int i, k = 0; if (pathname[0] == NULL) { pathname[0] = "./"; } for (i = 0; pathname[i]; i++) { if (k++) printf("\n"); key_ls(pathname[i],optbuf); } } int main(int argc,char **argv) { int opt; int flag = 1; int k = 0; char *pathname[SIZE]; char optbuf[3] = {0}; while ((opt = getopt(argc,argv,"-lan")) != -1) { flag = 0; switch (opt) { case 1: pathname[k++] = argv[optind-1]; break; //-l case 'l': optbuf[0] = 'l'; break; //-a case 'a': optbuf[1] = 'a'; break; //-n case 'n': optbuf[2] = 'n'; break; } } /* 未输入路径,默认为当前路径 */ if (flag) pathname[k++] = "./"; func(pathname,optbuf); exit(0); }
这篇关于Linux下c实现ls的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法