使用linux c 实现linux控制台 ls 命令
来源:互联网 发布:婚纱照软件哪个好 编辑:程序博客网 时间:2024/06/05 20:22
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <error.h>#include <time.h>// ctime()函数#include <dirent.h>//操作目录#include <sys/stat.h>//操作文件#include <pwd.h>// 获取文件所有者#include <grp.h>//InfoModeAll -a InfoModeDetail -l//显示信息模式typedef enum _InfoMode { InfoModeBothNo,InfoModeAll,InfoModeDetail,InfoModeBoth} InfoMode;//目录元素种类(文件、目录)enum ItemCategory { ItemCategoryDir, ItemCategoryFile };//显示目录中元素列表void display_dirItemList(char *path, int isAll);//显示目录中元素信息void display_dirItemInfo(char *path, int isAll);//显示目录信息void display_singleDirInfo(char *path);//显示文件信息void display_singleFileInfo(char *path);//显示文件名,根据文件路径void display_fileName(char *path);//显示文件信息void display_fileInfo(char *path, InfoMode mode);//显示目录信息void display_dirInfo(char *path, InfoMode mode);//解析命令行参数,返回,显示信息模式InfoMode AnalyticalParm(int argc, char **arg);//获取完整路径void getAbsolutePath(char *path);//检查path是否为绝对路径,0 不是,是相对路径 1 是绝对路径int checkPathIsAbsolutePath(char *path);//获取目录下的文件/目录名称,返回char **(这个变量需要动态释放),以及fileNameCountvoid getFileNameListFormDir(char *path,int isAll,char fileNameList[][10],int *fileNameCount);//打印目录元素的属性void Demonstrate_attribute(struct stat buf);//判断元素是文件还是目录int checkPathIsFile(char *path);int main(int argc, char **arg) { /* argc = 3; arg[0] = "./my_ls"; arg[1] = "-a"; arg[1] = "-l"; arg[2] = "/home/pengjing/文档/10-文件读写/my_ls/bin/Debug/test/"; //int i; //for(i=0; i<argc; i++) { //printf("%s\t",arg[i]); //} //printf("\n"); */ InfoMode mode = AnalyticalParm(argc, arg); char *path = arg[argc-1]; //判断是否为文件名,还是目录名,当res_index为0时,是目录名,当res_index为.所在的索引时为文件名 getAbsolutePath(path); //过滤最后一个"/" if(path[strlen(path)-1] == '/'){ path[strlen(path)-1] = '\0'; } int isFile = checkPathIsFile(path); if(isFile == 1) { display_fileInfo(path,mode); } else { display_dirInfo(path,mode); } return 0;}void display_dirItemList(char *path, int isAll) { int fileNameCount = 0; char fileNames[30][10]; getFileNameListFormDir(path,isAll,fileNames,&fileNameCount); int i; for(i=0;i<fileNameCount;i++){ printf("%-s\t",fileNames[i]); } printf("\n");}void display_dirItemInfo(char *path, int isAll) { int fileNameCount = 0; char fileNameList[30][10]; char filePathList[30][100]; int i,j; getFileNameListFormDir(path,isAll,fileNameList,&fileNameCount); for(i=0; i<fileNameCount; ++i) { char filePath[90] = {'\0'}; strcpy(filePath,path); strcat(filePath,"/"); strcat(filePath,fileNameList[i]); strcpy(filePathList[i],filePath); } struct stat _stat; for(i=0; i<fileNameCount; i++) { //bzero(_stat,sizeof(struct stat)); //printf("%s\n",filePathList[i]); // /home/pengjing/document/10-文件读写/my_ls/bin/Debug/test/file1 // char *myPath = "/home/pengjing/document/10-文件读写/my_ls/bin/Debug/test/file1"; int res_lstat = lstat(filePathList[i],&_stat); if(res_lstat == -1) { perror("lstat"); exit(0); } Demonstrate_attribute(_stat); }}void getFileNameListFormDir(char *path,int isAll,char fileNameList[][10],int *fileNameCount) { struct dirent *diren; DIR *dir; *fileNameCount = 0; //printf("fileNameList size :%ld\n",sizeof(fileNameList)); if((dir = opendir(path)) == NULL) { perror("opendir"); } while((diren = readdir(dir)) != NULL) { char *name = diren->d_name; if(isAll == 0 && name[0] == '.') { continue; } strcpy(fileNameList[*fileNameCount],name); (*fileNameCount)++; } closedir(dir);}//显示文件信息void display_singleFileInfo(char *path) { //printf("显示单个文件信息\n"); struct stat _stat; int res_lstat = lstat(path,&_stat); if(res_lstat == -1) { perror("lstat"); exit(0); } Demonstrate_attribute(_stat);}void display_fileName(char *path){ //printf("显示文件名"); char res[10],*a; a = rindex(path,'/'); strcpy(res,a); int i; for(i=1;i<strlen(res);i++){ res[i-1] = res[i]; } res[i-1] = '\0'; printf("%s\n",res);}//显示文件信息void display_fileInfo(char *path, InfoMode mode) { //printf("显示文件的详细信息 mode:%d\n",mode); //根据显示模式显示内容 switch(mode) { case InfoModeBothNo: { //显示目录中元素的名称 display_fileName(path); break; } case InfoModeAll: { //显示目录中所有元素的名称 display_fileName(path); break; } case InfoModeDetail: { //显示目录下元素的信息 display_singleFileInfo(path); break; } case InfoModeBoth: { //显示目录下所有元素的信息 display_singleFileInfo(path); break; } default : { //mode 错误 printf("mode 错误"); exit(0); break; } }}//显示目录信息void display_dirInfo(char *path, InfoMode mode) { //printf("显示目录的详细信息 mode:%d\n",mode); //根据显示模式显示内容 switch(mode) { case InfoModeBothNo: { //显示目录中元素的名称 display_dirItemList(path,0); break; } case InfoModeAll: { //显示目录中所有元素的名称 display_dirItemList(path,1); break; } case InfoModeDetail: { //显示目录下元素的信息 display_dirItemInfo(path,0); break; } case InfoModeBoth: { //显示目录下所有元素的信息 display_dirItemInfo(path,1); break; } default : { //mode 错误 printf("mode 错误"); exit(0); break; } }}//解析命令行参数,返回parmCount(参数个数),显示信息模式InfoMode AnalyticalParm(int argc, char **arg) { int i; InfoMode mode = InfoModeBothNo; for(i = 1 ; i < argc; i++) { if(arg[i][0] == '-') { if(arg[i][1] == 'a') { if(mode == InfoModeDetail) { mode = InfoModeBoth; break; } mode = InfoModeAll; } else if(arg[i][1] == 'l') { if(mode == InfoModeAll) { mode = InfoModeBoth; break; } mode = InfoModeDetail; } } } return mode;}int checkPathIsAbsolutePath(char *path) { int res = 0; if(path[0] == '/' || path[0] == '~') { res = 1; } return res;}//获取文件属性并打印void Demonstrate_attribute(struct stat buf){ char buf_time[32]; //存放时间 struct passwd *psd; //从该结构体中获取文件所有者的用户名 struct group *grp; //从该结构体中获取文件所有者所属组的组名/* 我们使用最多的属性是st_mode.通过着属性我们可以判断给定的文件是一个普通文件还是一个目录,连接等等.可以使用下面几个宏来判断. S_ISLNK(st_mode):是否是一个连接 S_ISREG是否是一个常规文件 S_ISDIR是否是一个目录 S_ISCHR是否是一个字符设备 S_ISBLK是否是一个块设备 S_ISFIFO是否是一个FIFO文件 S_ISSOCK是否是一个SOCKET文件 S_IFMT 0170000 文件类型的位遮罩 S_IFSOCK 0140000 socket S_IFLNK 0120000 符号链接(symbolic link) S_IFREG 0100000 一般文件 S_IFBLK 0060000 区块装置(block device) S_IFDIR 0040000 目录 S_IFCHR 0020000 字符装置(character device) S_IFIFO 0010000 先进先出(fifo) S_ISUID 0004000 文件的(set user-id on execution)位 S_ISGID 0002000 文件的(set group-id on execution)位 S_ISVTX 0001000 文件的sticky位 S_IRWXU 00700 文件所有者的遮罩值(即所有权限值) S_IRUSR 00400 文件所有者具可读取权限 S_IWUSR 00200 文件所有者具可写入权限 S_IXUSR 00100 文件所有者具可执行权限 S_IRWXG 00070 用户组的遮罩值(即所有权限值) S_IRGRP 00040 用户组具可读取权限 S_IWGRP 00020 用户组具可写入权限 S_IXGRP 00010 用户组具可执行权限 S_IRWXO 00007 其他用户的遮罩值(即所有权限值) S_IROTH 00004 其他用户具可读取权限 S_IWOTH 00002 其他用户具可写入权限 S_IXOTH 00001 其他用户具可执行权限*/ //获取并打印文件类型 if (S_ISLNK(buf.st_mode)){ //判断是否为符号链接 printf("l"); }else if (S_ISREG(buf.st_mode)){ //判断是否为文件 printf("-"); }else if (S_ISDIR(buf.st_mode)){ //判断是否为目录 printf("d"); }else if (S_ISCHR(buf.st_mode)){ //判断是否为字符设备文件 printf("c"); }else if (S_ISBLK(buf.st_mode)){ //判断是否为块设备文件 printf("b"); }else if (S_ISFIFO(buf.st_mode)){ //判断是否为先进先出的FIFO printf("f"); }else if (S_ISSOCK(buf.st_mode)){ //判断是否为socket printf("s"); } //获取并打印文件所有者的权限 //按位与结果作为条件判断,应当判断其与结果为0还是非0数值 当前比较的是buf.st_mode在用户读权限的位与S_IRUSR是否相等 if (buf.st_mode & S_IRUSR){ printf("r"); }else{ printf("-"); } if (buf.st_mode & S_IWUSR){ printf("w"); }else{ printf("-"); } if (buf.st_mode & S_IXUSR){ printf("x"); }else{ printf("-"); } //获取并打印与文件所有者同组的用户对该文件的操作权限 if(buf.st_mode & S_IRGRP){ printf("r"); }else{ printf("-"); } if(buf.st_mode & S_IWGRP){ printf("w"); }else{ printf("-"); } if(buf.st_mode & S_IXGRP){ printf("x"); }else{ printf("-"); } //获取并打印其它用户的对该文件的操作权限 if (buf.st_mode & S_IROTH){ printf("r"); }else{ printf("-"); } if (buf.st_mode & S_IWOTH){ printf("w"); }else{ printf("-"); } if (buf.st_mode & S_IXOTH){ printf("x"); }else{ printf("-"); } printf(" "); //根据uid与gid获取文件所有者的用户名与组名 psd = getpwuid(buf.st_uid); grp = getgrgid(buf.st_gid); printf("%4d ",buf.st_nlink); //打印文件的链接数(该文件硬链接数目) printf("%-9s", psd->pw_name); //打印文件拥有者 printf("%-8s", grp->gr_name); //打印文件所属用户组 printf("%6d",(int)buf.st_size); // 打印文件的大小 char *wo = ctime(&buf.st_mtime); strcpy(buf_time, ctime(&buf.st_mtime)); buf_time[strlen(buf_time) - 1] = '\0'; // 去掉换行符 printf(" %s\n", buf_time); // 打印文件的时间信息}int checkPathIsFile(char *path){ int res = 0; struct stat _stat; int res_lstat = lstat(path,&_stat); if(res_lstat == -1){ perror("lstat"); exit(0); } if(S_ISREG(_stat.st_mode)){ //判断是否为文件 res = 1; } return res;}void getAbsolutePath(char *path){ //组建绝对路径 char absPath[100]; int isAbsolutePath = checkPathIsAbsolutePath(path); if(isAbsolutePath == 1) { //absPath = (char *)malloc(sizeof(char) * strlen(path)); strcpy(absPath,path); } else { if(getcwd(absPath,200) == NULL) { perror("获取当前工作目录失败"); } strcat(absPath,"/"); strcat(absPath,path); //printf("absPath:%s\n",absPath); } path = absPath;}
0 0
- 使用linux c 实现linux控制台 ls 命令
- linux c实现ls命令
- 使用linux-c编程实现简单的ls命令
- linux ls命令实现
- linux命令实现:ls
- Linux ls命令实现
- linux ls命令使用
- linux c模拟ls命令
- Linux命令简单实现 -- ls
- Linux下ls命令实现
- 代码实现Linux ls命令
- C语言实现Linux下的ls命令。
- C语言实现的linux下ls命令
- Linux C变成小例子——实现ls命令
- C语言实现的linux下ls命令
- 在Linux下:用 C 语言实现 ls 命令
- 用c语言在Linux上实现ls命令
- Linux下的ls命令详解以及C语言实现
- LINUX 下chmod|chown|chgrp和用法和区别
- Ubuntu下彻底删除wine
- KeeperErrorCode = Unimplemented for /service 错误
- 一行jQuery代码搞定checkbox 全选和全不选
- C++学习笔记(更新中)
- 使用linux c 实现linux控制台 ls 命令
- Python字符编码详解
- 《剑指offer》连续子数组的最大和
- CSS的文本属性
- WebDriverWait类的介绍
- Unable to create 'E:/NFVdoc/.git/index.lock': File exists.解决方法
- 对称、非对称密码体制
- 挂机型外挂开发-脚本引擎
- C++常用小技巧个人总结(持续更新)