zoukankan      html  css  js  c++  java
  • Linux用C语言模拟‘ls‘命令

    原理

    在linux下使用C语言,通过调用Linux系统的目录访问API来实现一个类似于ls命令功能的小程序,主要是可以练习程序对命令的解析和目录API函数的使用。

    实现代码

    #include <stdio.h>
    #include <time.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <dirent.h>
    #include <pwd.h>
    #include <grp.h>
    
    int aflag = 0,lflag = 0;
    
    void display_file(char *fname , char *nname)
    {
    	struct stat buf;
    	struct tm *t;
    	int i;
    
    	if(stat(fname,&buf) < 0)
    	{
    		perror("stat error
    ");
    		return ;
    	}
    
    	switch(buf.st_mode & S_IFMT)
    	{
    	case S_IFSOCK:	printf("s");	break;
    	case S_IFLNK:	printf("l");	break;
    	case S_IFREG:	printf("-");	break;
    	case S_IFBLK:	printf("b");	break;
    	case S_IFDIR:	printf("d");	break;
    	case S_IFCHR:	printf("c");	break;
    	case S_IFIFO:	printf("p");	break;
    	}
    
    	for(i = 8 ; i >= 0 ; i--)
    	{
    		if(buf.st_mode & (1 << i))
    		{
    			if(i % 3 == 2)	printf("r");
    			if(i % 3 == 1)	printf("w");
    			if(i % 3 == 0)	printf("x");
    		}
    		else
    			printf("-");
    	}
    
    
    	printf(" %d ",buf.st_nlink);
    
    	printf("%s ",getpwuid(buf.st_uid)->pw_name);
    	printf("%s ",getgrgid(buf.st_gid)->gr_name);
    
    	printf("%ld ",buf.st_size);
    
    	t = localtime(&buf.st_mtime);
    	printf("%d-%02d-%02d  %02d:%02d ",t->tm_year+1900,t->tm_mon+1,t->tm_mday,
    			t->tm_hour,t->tm_min);
    	printf("%s
    ",nname);
    
    	return ;
    }
    
    void display_dir(char *dir)
    {
    	DIR *mydir;
    	struct dirent *myitem;
    	char fname[256];
    
    	if((mydir = opendir(dir)) == NULL)
    	{
    		perror("fail to opendir!
    ");
    		return ;
    	}
    	while((myitem = readdir(mydir)) != NULL)
    	{
    		if(myitem->d_name[0] == '.' && 
    		 !aflag)//如果if条件成立的就继续下一次循环,否则往下执行
    			continue;
    
    		if(lflag)//ls -l -a dir
    		{
    
    			sprintf(fname,"%s/%s",dir,myitem->d_name);
    			display_file(fname,myitem->d_name);
    		}
    		else // ls dir
    			printf("%s  ",myitem->d_name);
    	}
    	printf("
    ");
    	closedir(mydir);
    	return ;
    }
    
    int main(int argc,char *argv[])
    {
    	int ch,i;
    	struct stat buf;
    
    	opterr = 0;
    	//解析命令
    	while((ch = getopt(argc,argv,"la")) != -1)
    	{
    		switch(ch)
    		{
    		case 'a':	aflag = 1;	break;
    		case 'l':	lflag = 1;	break;
    		default:	printf("wrong option:%c
    ",optopt);return -1;
    		}
    	}
    
    	if(optind == argc)//no argument //ls .没有带参直接ls当前目录
    		display_dir(".");
    
    	for(i = optind; i < argc ; i++) //ls name1 name2....
    	{
    		if(stat(argv[i],&buf) < 0)
    		{
    			perror("fail to stat!
    ");
    			return -1;
    		}
    		if(S_ISDIR(buf.st_mode))//dir
    		{
    			printf("%s:
    ",argv[i]);
    			display_dir(argv[i]);
    		}
    		else//file
    			if(lflag)//ls -l file
    				display_file(argv[i],argv[i]);
    			else// ls file
    				printf("%s",argv[i]);
    		printf("
    ");
    	}
    
    	return 0;
    }
    
    

    编译

    gcc test.c -o test
    

    运行

    直接运行,输出当前目录的文件:

    ./test 
    test  test.c   
    
    

    跟个参数,输出详细信息:

    ./test -l
    -rwxrwxr-x 1 root root 13637 2020-04-15  07:37 test
    -rw-r--r-- 1 root root 2409 2014-03-25  06:01 test.c
    

    输出隐藏文件:

    ./test -a
    test  .test.c.bak  test.c  ..  .
    
  • 相关阅读:
    剑指Offer 从尾到头打印链表
    剑指Offer 斐波那契数列
    剑指Offer 替换空格
    剑指Offer 二维数组中的查找
    Java EE 学习(8):IDEA + maven + spring 搭建 web(4)- 用户管理
    Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库
    Java EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring
    Java EE 学习(5):IDEA + maven + spring 搭建 web(1)
    Java EE 学习(4):IDEA + maven 搭建 web(2)
    Java EE 学习(3):IDEA + maven 搭建 web(1)
  • 原文地址:https://www.cnblogs.com/fensnote/p/13436444.html
Copyright © 2011-2022 走看看