linux实现自己的ls

来源:互联网 发布:服务器架构设计软件 编辑:程序博客网 时间:2024/06/05 05:16
主体思路就是,先用readdir()函数获取输入的目录下的所有子目录和文件的名在加以补全,然后在用stat()函数打开文件,获取文件的详细信息,实现代码如下:
#include<stdio.h>#include<time.h>                    #include<unistd.h>#include<sys/stat.h>#include<sys/types.h>        //不完全,缺少容错性,及链接显示问题和执行权限x#include<stdlib.h>#include<grp.h>              #include<pwd.h>#include<string.h>#include<dirent.h>#include<stdlib.h>//a    显示隐藏文件//l    显示详细信息//R    显示详细目录//i    显示节点索引//n    将用户名和组名用uid,gid表示//f    不排序//r    逆排序void mls(char *name,int x,int y,int z,int u,int r,int mlsf,int mlsr)  //(a,l,R,i,n,mlsf,mlsr) {    DIR *dir;    struct stat buf;   //文件信息    struct passwd *p;        //获取文件所有者的名字    struct group *g;   //获取所有者所在组的名字    struct dirent *w;  //目录信息    int i=0,j,t,f,C=0,k=0,sum=0,m;    char a[1000][200],e[200],c[1000][200],b[50],d[1000][200];    if(z)        printf("\n%s:\n",name);    if((dir=opendir(name))==NULL)    {           printf("没有那个文件或目录\n");        return ;    }    while((w=readdir(dir))!=NULL)    {           if(x)        {            if( (t=strlen(strcpy(a[C],w->d_name))) > k )                k=t;            strcpy(c[C],w->d_name);            strcpy(a[C],name);            if(strcmp(name,"/"))                strcat(a[C],"/");            strcat(a[C++],w->d_name);        }        else        {            if(w->d_name[0]!='.')            {                   if( (t=strlen(strcpy(a[C],w->d_name))) > k )                    k=t;                strcpy(c[C],w->d_name);                strcpy(a[C],name);                if(strcmp(name,"/"))                    strcat(a[C],"/");                strcat(a[C++],w->d_name);            }               }    }    //文件名排序    if(!mlsf)    {        if(!mlsr)        {            for(i=0;i<C-1;i++)                for(j=0;j<C-1-i;j++)                    if(strcmp(a[j],a[j+1])>0)                    {                        strcpy(e,a[j]);                        strcpy(a[j],a[j+1]);       //a全路径  c相对路径                        strcpy(a[j+1],e);                        strcpy(e,c[j]);                        strcpy(c[j],c[j+1]);                        strcpy(c[j+1],e);                       }        }        else        {            for(i=0;i<C-1;i++)                for(j=0;j<C-1-i;j++)                    if(strcmp(a[j],a[j+1])<0)                        {                            strcpy(e,a[j]);                            strcpy(a[j],a[j+1]);       //a全路径  c相对路径                            strcpy(a[j+1],e);                            strcpy(e,c[j]);                            strcpy(c[j],c[j+1]);                            strcpy(c[j+1],e);                           }        }    }    if(y)               {        for(i=0;i<C;i++)        {               stat(a[i],&buf);            sum+=buf.st_size;        }        printf("文件总大小%d(KB)  文件总数%d\n",sum/1024,C);    }    for(i=0,m=0;i<C;i++)    {           if(stat(a[i],&buf))      //它可以自动识别相对路径下的文件            printf("获取文件属性失败");        if(u)            printf("%7ld  ",buf.st_ino);        if(y)        {                //文件类型        if( S_ISLNK(buf.st_mode) )            printf("l");        if( S_ISREG(buf.st_mode) )            printf("-");        if( S_ISDIR(buf.st_mode) )            printf("d");        if( S_ISCHR(buf.st_mode) )            printf("c");        if( S_ISBLK(buf.st_mode) )            printf("b");        if( S_ISFIFO(buf.st_mode) )            printf("f");        if( S_ISSOCK(buf.st_mode) )            printf("s");        //文件权限/所有者        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("  ");        //文件个数        printf("%3ld",buf.st_nlink);        printf("  ");        //文件所有者        p=getpwuid(buf.st_uid);        if(r)            printf("%5d",buf.st_uid);        else            printf("%6s",p->pw_name);        printf("  ");        //文件所有者所在组        g=getgrgid(buf.st_gid);        if(r)            printf("%5d",buf.st_gid);        else            printf("%6s",g->gr_name);        printf("  ");        //文件大小        printf("%8ld",buf.st_size);        printf("  ");        //文件最后一次被修改的时间        strcpy(b,ctime(&buf.st_mtime));        b[strlen(b)-1]='\0';                 //×去掉换行符×        printf("%s",b);        printf("  ");        //文件名        printf("%s\n",c[i]);         }        if(z)            if( S_ISDIR(buf.st_mode) )                if( strcmp(c[i],".") && strcmp(c[i],"..") )                    strcpy(d[m++],a[i]);        if(!y)            if( x || z || (!x&&!y&&!z || w))            {                if( (t=strlen(c[i])) < k)                {                       for(f=t;f<k;f++)                        c[i][f]=' ';                    c[i][f]='\0';                   }                printf("%s  ",c[i]);                if((i+1)%5==0)                    if(i!=C-1)                        printf("\n");            }    }    printf("\n");    if(z)        for(i=0;i<m;i++)            mls(d[i],x,y,z,u,r,mlsf,mlsr);    closedir(dir);}int main(int argc,char *argv[]){    int i,t=-1,x=0,y=0,z=0,w=0,n=0,f=0,r=0;    char ml[50];     getcwd(ml,50);  //获取当前目录路径    switch(argc)                       {        case 1:mls(ml,x,y,z,w,n,f,r);break;        case 2:                if(argv[1][0]!='-')                    mls(argv[1],x,y,z,w,n,f,r);                else                        {                    for(i=1;i<strlen(argv[1]);i++)                        {                            if(argv[1][i]=='a')                                                   x=1;                            if(argv[1][i]=='l')                                y=1;                            if(argv[1][i]=='R')                                z=1;                            if(argv[1][i]=='i')                                w=1;                                                if(argv[1][i]=='n')                            {                                n=1;                                y=1;                            }                            if(argv[1][i]=='f')                                f=1;                            if(argv[1][i]=='r')                                r=1;                        }                    mls(ml,x,y,z,w,n,f,r);                }                break;        case 3:                if(argv[1][0]!='-')                    return printf("参数输入有误");                else                        {                    for(i=1;i<strlen(argv[1]);i++)                    {                        if(argv[1][i]=='a')                                                     x=1;                        if(argv[1][i]=='l')                            y=1;                        if(argv[1][i]=='R')                            z=1;                        if(argv[1][i]=='i')                            w=1;                                if(argv[1][i]=='n')                        {                            n=1;                            y=1;                        }                        if(argv[1][i]=='f')                            f=1;                        if(argv[1][i]='r')                            r=1;                    }                    mls(argv[2],x,y,z,w,n,f,r);                }                break;        case 4:        case 5:        case 6:        case 7:        case 8:printf("只接受四个以下的参数,第三个参数时第二个参数为a l R f i n r的组合\n");    }}

存在的问题主要有: 对命令的解析不够完全,在R是由于文件很多导致段错误.

0 0