您好,欢迎访问三七文档
1.LINUX实验二编程遍历文件目录1.1实验目的练习vi,使用Linux的系统调用和库函数,体会Shell文件通配符的处理方式以及命令对选项的处理方式。1.2实验内容编程实现程序list.c,列表普通磁盘文件(不考虑目录和设备文件等),列出文件名和文件大小。与ls命令类似,命令行参数可以有0到多个0个参数:列出当前目录下所有文件参数为普通文件:列出文件参数为目录:列出目录下所有文件实现自定义选项r,a,l,h,m以及--r递归方式列出子目录a列出文件名第一个字符为圆点的普通文件(默认情况下不列出文件名首字符为圆点的文件)l后跟一整数,限定文件大小的最小值(字节)h后跟一整数,限定文件大小的最大值(字节)m后跟一整数n,限定文件的最近修改时间必须在n天内--显式地终止命令选项分析1.3实验步骤编辑,编译vilist.cmakelist或者cclist.c–olist运行举例./list–l100–h5000/bin/etc列出大小在100~5000之间的文件./list–ar-l50000–m2递归式列出当前目录树下文件大小超50KB并且2天内修改过的文件(包括文件名首字符为圆点的文件)./list---l./list*延伸学习用于处理命令选项的库函数getopt,getopt_long体会这两个函数功能的设计思想1.4实验具体过程1.4.1Gcc安装首先在进行实验前,我对linux编译c代码很是不熟悉,后来在网上查找语句,发现了gcc;但是由于之前没有安装,需要先安装gcc。未安装时使用gcc语句会给出提示,具体没截图。在命令行用sudoapt-getinstallgcc便可以完成gcc安装。1.4.2编译使用gcc–olistlist.c命令进行编译,编译通过之后才可以正常的如同ls指令一样使用。如果代码不通过会出现编译报错,下图我展示了通过和报错两种情况1.未报错情况:2.报错情况:1.4.3简单命令运行——目录选择首先,我们不进行任何选项的添加,直接输入一个目录,例如:将Desktop桌面的各个文件展示:命令:./list+目录名(/Desktop)显示结果中,我输出了文件名+文件类型+文件大小+文件最近修改时间(下面的输出也是如此,不做赘述)1.4.4简单命令运行——L选项L选项:./list–l5000(size)+目录:筛选出目录下的文件大小size的文件信息此处,我筛选了Desktop的桌面文件(之后我都已默认按桌面的目录进行实验,下面不做赘述)1.4.5简单命令运行——h选项h选项:./list–h5000(size)+目录:筛选出目录下的文件大小size的文件信息1.4.6简单命令运行——a选项A选项:./list–a+目录:列出文件名第一个字符为圆点的普通文件1.4.7简单命令运行——r选项R选项:/list–r+目录:递归列出目录下的所有文件信息1.4.8简单命令运行——m选项M选项:/list–m4(time)+目录:列出目录下的在time天内修改过的文件信息1.4.9组合命令运行——示例1命令:./list–l5000–h10000–m1:找出在主目录下的文件大小在5000到10000之间,并且在1天内被修改过的文件信息。1.4.10组合命令运行——示例2命令:./list–ar–l5000/Desktop:递归找出在桌面Desktop目录树下下的文件大小大于5000的文件信息1.4.11组合命令运行——示例3命令:./list–r–l5/Desktop/1:递归找出/Desktop/1目录下的大小大于5的文件信息1.4.12List拓展运行——多目录选择此次实验激起了我的一些兴趣,便随意修改了下list的其他实现,让其可以选中多个目录进行文件信息展示(两个目录之间需要用空格隔开):例如命令:./list–r/Desktop/Desktop/1:此时输入了/Desktop和/Desktop/1两个目录:1.5代码分析及展示1.5.1代码分析1.5.1.1结构定义structpath{char*path;//当前目录structpath*next;//下一目录};//文件路径链表,在拓展功能中的多目录中使用,将多个路径存入链表,依次访问。structoptions//命令获取{boolaFlag,rFlag,lFlag,hFlag,mFlag;//thesignofa.r.l.h.mlonglValue,hValue;//thevalueafterl.hintmValue;//thevalueafterm};//代表一条命令其中有是否具有:a/r/l/h/m选项的标志l/h/m选项后跟的数值1.5.1.2输出说明1.对于每一个目录:输出分隔标志******;printf(***************************************************************\n);输出文件信息标识:文件名+文件类型+文件大小+文件最近修改时间printf(%-20s%-20s%-10s%s\n,name,type,length,m_time);输出对应文件目录:printf(%s:\n,pathHead-path);之后才会输出具体筛选出的文件详细信息。2.m_time的输出使用ctime函数ctime(&info.st_mtime),转换为字符串输出3.文件类型输出使用st_mode&S_IFMT来筛选switch(info.st_mode&S_IFMT){caseS_IFLNK:printf(%-20s,symboliclink);break;caseS_IFREG:printf(%-20s,regularfile);break;caseS_IFDIR:printf(%-20s,directory);break;caseS_IFCHR:printf(%-20s,characterdevice);break;caseS_IFIFO:printf(%-20s,FIFOpipe);break;default:printf(%-20s,otherfile);break;}1.5.1.3特别说明1.对于命令行工具来编译c语言代码,我们必须详细了解一下main函数中的参数argc和*args,其中args中存储各段字符串,其中依靠空格隔开。因此,对于目录的处理,我们需要仔细考虑是否需要将‘/’符号考虑或删除。2.对于筛选文件的操作:因为命令中可能会有好多选项,因此在选择时,秩序进行单个选项判断,删除其中不满足要求的,然后进行文件信息输出。这样相对于直接筛选满足要求的要简单很多。例如,我的代码中采用的:if(option.aFlag==false&&fileName[0]=='.')//areturnfalse;if(option.lFlag==true&&(long)info.st_sizeoption.lValue)//lreturnfalse;if(option.hFlag==true&&(long)info.st_sizeoption.hValue)//hreturnfalse;longcurrentTime=(long)time(NULL);if(option.mFlag==true&&(currentTime-(long)info.st_mtime)/86400=option.mValue)//mreturnfalse;returntrue;3.注意对相连选项的处理:例如./list–ar等1.5.2代码展示#includestdio.h#includestdlib.h#includestring.h#includesys/stat.h#includesys/types.h#includetime.h#includestdbool.h#includedirent.h#defineLENGTH100structpath{char*path;structpath*next;};structoptions{boolaFlag,rFlag,lFlag,hFlag,mFlag;//theaignofa.r.l.h.mlonglValue,hValue;//thevalueafterl.hintmValue;//thevalueafterm};boolis_digit(charch);boolis_print(structoptionsoption,structstatinfo,char*fileName);intget_value(char*option);voidlist_info(char*path,structoptionsoption);intmain_option_path(intargc,char**args);intmain(intargc,char*argv[]){main_option_path(argc,argv);return0;}//determinewhetherthecharacteristhenumberboolis_digit(charch){if(ch='0'&&ch='9')returntrue;elsereturnfalse;}//determinewhetherthefileneedtoprintboolis_print(structoptionsoption,structstatinfo,char*fileName){if(option.aFlag==false&&fileName[0]=='.')//areturnfalse;if(option.lFlag==true&&(long)info.st_sizeoption.lValue)//lreturnfalse;if(option.hFlag==true&&(long)info.st_sizeoption.hValue)//hreturnfalse;longcurrentTime=(long)time(NULL);if(option.mFlag==true&&(currentTime-(long)info.st_mtime)/86400=option.mValue)//mreturnfalse;returntrue;}//getthevalueafteranoptionintget_value(char*opValue){inti=0;intvalue=0;for(;opValue[i]!='\0';i++){if(is_digit(opValue[i]))value=value*10+opValue[i]-'0';elsereturn-1;}returnvalue;}//printthefileanditsinformationvoidlist_info(char*path,structoptionsoption){DIR*dir;structdirent*files;boolisPrint;structstatinfoTmp;if(stat(path,&infoTmp)!=-1&&!S_ISDIR(infoTmp.st_mode)){printf(%-20s,path);switch(infoTmp.st_mode&S_IFMT){caseS_IFLNK:printf(%-20s,symboliclink);break;caseS_IFREG:printf(%-20s,regularfile);break;caseS_IFDIR:printf(%-20s,directory);break;caseS_IFCHR:printf(%-20s,characterdevice);break;caseS_IFIFO:printf(%-20s,FIFOpipe);break;default:printf(%-20s,otherfile);break;}printf(%-10ld
本文标题:ls模拟
链接地址:https://www.777doc.com/doc-4803748 .html