高仿linux下的ls -l命令——C语言实现

主要用到的函数可以参考头文件,仅仅支持ls -l这功能,扩展就交给大家了0.0

相关测试图片:

?

?

话不多说,直接上码

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/stat.h>
  5 #include <sys/types.h>
  6 #include <string.h>
  7 #include <time.h>
  8 #include <pwd.h>
  9 #include <grp.h>
 10 #include <time.h>
 11 #include <dirent.h>
 12
 13 #define MAX_FILE_NUM 200
 14
 15
 16 //可能还有一些小问题没有解决,功能基本已经实现,如有建议,望大佬赐教
 17
 18 typedef struct LS
 19 {
 20     char mode[15];    // 文件的模式
 21     int dir_num;    // 是否目录或目录中包含目录的数量
 22     char user[20];    // 文件的用户名
 23     char group[20];    // 文件的组名
 24     long size;        // 文件的字节数
 25     char time[30];    // 文件的最后修改时间
 26     char year[5];    // 拓展用,年份
 27     char mon[5];    // 月份
 28     char hour[5];    // 时
 29     char min[5];    // 分
 30     int st_mode;    // 文件类型和权限
 31     char name[20];    // 文件名
 32 }LS;
 33
 34 // 获取文件的模式
 35 char* file_mode(mode_t m,char* str)
 36 {
 37     if(S_ISREG(m))
 38         str[0] = ‘-‘;
 39     else if(S_ISDIR(m))
 40         str[0] = ‘d‘;
 41     else if(S_ISCHR(m))
 42         str[0] = ‘c‘;
 43     else if(S_ISBLK(m))
 44         str[0] = ‘b‘;
 45     else if(S_ISFIFO(m))
 46         str[0] = ‘q‘;
 47     else if(S_ISLNK(m))
 48         str[0] = ‘l‘;
 49 //    else if(S_ISSOCK(m))
 50 //        str[0] = ‘s‘;
 51     else
 52         str[0] = ‘?‘;
 53
 54     str[1] = ‘\0‘;
 55
 56     strcat(str,S_IRUSR&m?"r":"-");
 57     strcat(str,S_IWUSR&m?"w":"-");
 58     strcat(str,S_IXUSR&m?"x":"-");
 59
 60     strcat(str,S_IRGRP&m?"r":"-");
 61     strcat(str,S_IWGRP&m?"w":"-");
 62     strcat(str,S_IXGRP&m?"x":"-");
 63
 64     strcat(str,S_IROTH&m?"r":"-");
 65     strcat(str,S_IWOTH&m?"w":"-");
 66     strcat(str,S_IXOTH&m?"x":"-");
 67
 68     return str;
 69 }
 70
 71 // 获取目录的数量
 72 int dir_count(char* path)
 73 {
 74     DIR *dir;
 75     dir = opendir(path);
 76     struct dirent *dirent;
 77     int count = 0;
 78     while((dirent = readdir(dir)) != NULL)
 79     {
 80         if(dirent->d_type == 4)
 81             count++;
 82     }
 83     closedir(dir);
 84     return count;
 85 }
 86
 87 // 是否是目录或目录下有目录
 88 int is_dir(struct dirent *dirent)
 89 {
 90     char* a = dirent->d_name;
 91     if(dirent->d_type == 8)
 92         return 1;
 93     if(dirent->d_type == 4)
 94     {
 95         if(dir_count(a) == 0)
 96             return 2;
 97         else
 98             return dir_count(a);
 99     }
100 }
101
102 // 获取用户名
103 char* file_user(uid_t st_uid,char* str)
104 {
105     struct passwd *user;
106     user = getpwuid(st_uid);
107     sprintf(str,"%s",user->pw_name);
108     return str;
109 }
110
111 // 获取组名
112 char* file_group(uid_t st_uid,char* str)
113 {
114     struct passwd *user;
115     user = getpwuid(st_uid);
116     struct group *grp;
117     grp = getgrgid(user->pw_gid);
118     sprintf(str,"%s",grp->gr_name);
119     return str;
120 }
121
122 // 获取文件大小
123 off_t file_size(struct stat buf)
124 {
125     off_t size = buf.st_size;
126     return size;
127 }
128
129 // 获取最后修改时间
130 char* file_time(time_t mt,char* str)
131 {
132     struct tm* t = localtime(&mt);
133     sprintf(str,"%d月 %02d %02d:%02d",t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min);
134     return str;
135 }
136
137 // 获取文件的数量
138 int file_count(char* path)
139 {
140     DIR *dir;
141     dir = opendir(path);
142     struct dirent *dirent;
143     int count = 0;
144     while((dirent = readdir(dir)) != NULL)
145     {
146         count++;
147     }
148     closedir(dir);
149     return count;
150 }
151
152 // 交换
153 void equal(LS *a,LS *b)
154 {
155     strcpy(a->mode,b->mode);
156     a->dir_num = b->dir_num;
157     strcpy(a->user,b->user);
158     strcpy(a->group,b->group);
159     a->size = b->size;
160     strcpy(a->time,b->time);
161     a->st_mode = b->st_mode;
162     strcpy(a->name,b->name);
163 }
164
165 // 排序
166 void sort(LS *info,int index)
167 {
168     LS *temp = (LS*)malloc(sizeof(LS));
169     for(int i=index-1; i>0; i--)
170     {
171         for(int j=0; j<i; j++)
172         {
173             if(strcmp(info[i].name,info[j].name)<0)
174             {
175                 equal(temp,&info[i]);
176                 equal(&info[i],&info[j]);
177                 equal(&info[j],temp);
178             }
179         }
180     }
181 }
182
183 // 输出结构体
184 void show_ls(LS *info,int index)
185 {
186     for(int i=0; i<index; i++)
187     {
188         //printf("%d: ",i);
189         printf("%s \033[0m",info[i].mode);
190         printf("%d ",info[i].dir_num);
191         printf("%s ",info[i].user);
192         printf("%s ",info[i].group);
193         printf("%5ld ",info[i].size);
194         printf(" %s ",info[i].time);
195         //printf("%d ",info[i].st_mode);
196         if(16893 == info[i].st_mode)
197         {
198             // 颜色
199             printf("\033[34m\033[1m%s\033[0m",info[i].name);
200         }
201         else if(33277 == info[i].st_mode)
202         {
203             printf("\033[32m\033[1m%s\033[0m",info[i].name);
204         }
205         else
206         {
207             printf("%s",info[i].name);
208         }
209         if(i < index)
210             printf("\n");
211     }
212     //printf("循环结束\n");
213 }
214
215 // 创建结构体,赋值
216 LS *create(struct stat buf,struct dirent *dirent)
217 {
218     LS* info = (LS*)malloc(sizeof(LS));
219     char str[50] = {};
220     //puts(file_mode(buf.st_mode,str));
221     strcpy(info->mode,file_mode(buf.st_mode,str));
222     //puts(info->mode);
223     info->dir_num = is_dir(dirent);
224     strcpy(info->user,file_user(buf.st_uid,str));
225     strcpy(info->group,file_group(buf.st_uid,str));
226     info->size = file_size(buf);
227     strcpy(info->time,file_time(buf.st_mtime,str));
228     info->st_mode = buf.st_mode;
229     strcpy(info->name,dirent->d_name);
230
231     return info;
232 }
233
234 int main(int argc,char* argv[])
235 {
236     LS info[MAX_FILE_NUM];
237     char* l = "-l";
238     if(strcmp(argv[1],l) != 0)
239     {
240         printf("\"ls:无法识别的选项\"%s\"\n",argv[1]);
241         printf("请尝试执行\"ls --help\"来获取更多信息。\n");
242         return 0;
243     }
244     char* a = ".";
245     char* b = "..";
246     char* path = malloc(10000);
247     strcpy(path,"./");    // 只支持当前路径
248     int count = file_count(path);
249
250     DIR *dir;
251     dir = opendir(path);
252     struct dirent *dirent;
253     int index = 0;    // 结构体下标
254     int blocks = 0;
255     for(int i=0; i<count; i++)
256     {
257         dirent = readdir(dir);
258         struct stat buf = {};
259         if(stat(dirent->d_name,&buf))
260         {
261             perror("stat");
262             return -1;
263         }
264
265         // 跳过特殊情况
266         if(strcmp(dirent->d_name,a)==0 || strcmp(dirent->d_name,b)==0)
267             continue;
268         blocks += buf.st_blocks;
269         //printf("%d\n",blocks);
270         info[index++] = *create(buf,dirent);
271     }
272     closedir(dir);
273     //printf("文件总数:%d\n",index);
274     //show_ls(info,index);
275
276     printf("总用量 %d\n",blocks/2);
277     sort(info,index);
278     show_ls(info,index);
279     return 0;
280 }

原文地址:https://www.cnblogs.com/ikaros-521/p/11254332.html

时间: 2024-08-28 21:36:09

高仿linux下的ls -l命令——C语言实现的相关文章

实现Linux下的ls -l命令

基本实现了Linux下的ls -l命令,对于不同的文件显示不同的颜色和显示符号链接暂时没有实现: 1 /************************************************************************* 2 > File Name: dirwalk.c 3 > Author: 4 > Mail: 5 > Created Time: Tue 31 Mar 2015 11:56:38 AM CST 6 ******************

模拟linux下的ls -l命令

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <dirent.h> #include <sys/types.h> #include <sys/stat.h> #include <time.h> #define ERR_EXIT(m)

编程实现Linux下的ls -l

头文件 #ifndef __FUNC_H__ #define __FUNC_H__ #include<stdio.h> #include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #inc

Linux下的ls 常用命令

ls是linux下最常用的命令之一.下面列出常用的几个命令 ls  :展示当前目录下所有非隐藏的文件. ls -a :列出目录下的所有文件,包含以.开头的隐含文件. ls -l :列出文件的详细信息. ls -s :在每个文件名后输出该文件的大小 ls -r : 对目录方向排序 ls -t : 以时间排序 ls -u : 以文件上次被访问的时间排序 ls -S : 以文件大小排序 ls -X :以文件的扩展名(最后一个.后的字符)排序 ls -1 : 一行只显示一个文件 ls --help:在标

Linux系统中的“ls -l”命令

ls -l命令的输出颜色及含义 颜色 代表的文件类型 白色 普通文件 蓝色 目录 绿色 可执行文件 红色 压缩文件 浅蓝色 链接文件 红色闪烁 链接文件有问题 黄色 设备文件 灰色 其他文件 ls -l命令信息 例:drwxr-xr-x 2 samite samite 4096 9月 25 09:19 exp 分别代表:文件的类型(d--目录文件 ---文本文件...) 文件的可执行权限 所属组的权限 其它组的权限 硬链接数或目录子目录数 文件拥有者 文件拥有者组 文件大小(byte) 时间 文

linux下如何使用sftp命令【转】

linux下如何使用sftp命令 from:   http://www.cnblogs.com/chen1987lei/archive/2010/11/26/1888391.html sftp 是一个交互式文件传输程式.它类似于 ftp, 但它进行加密传输,比FTP有更高的安全性.下边就简单介绍一下如何远程连接主机,进行文件的上传和下载,以及一些相关操作. 举例,如远程主机的 IP 是 202.206.64.33或者是域名www.hebust.edu.cn,用户名是  fyt ,在命令行模式下:

linux下find和grep命令详解

在linux下面工作,有些命令能够大大提高效率.本文就向大家介绍find.grep命令,他哥俩可以算是必会的linux命令,我几乎每天都要用到他们.本文结构如下: find命令 find命令的一般形式 find命令的常用选项及实例 find与xargs grep命令 grep命令的一般形式 grep正则表达式元字符集(基本集) grep命令的常用选项及实例 1.find命令 find命令是一个无处不在命令,是linux中最有用的命令之一.find命令用于:在一个目录(及子目录)中搜索文件,你可以

linux下find(文件查找)命令的详解

文件查找命令locate和find详解 locate 配合数据库缓存,快速查看文件位置,非实时查找( 数据库查找) find 实际搜寻硬盘查询文件名称 ,实时查找 locate简介 locate命令其实是find -name的另一种写法,但是要比后者快得多,原因在于它不搜索具体目录,而是搜索一个数据库/var/lib/locatedb,这个数据库中含有本地所有文件信息.Linux系统自动创建这个数据库,并且每天自动更新一次,所以使用locate命令查不到最新变动过的文件.为了避免这种情况,可以在

二十七、Linux下常用的shell命令记录

本文章记录我在linux系统下常用或有用的系统级命令,包括软硬件查看.修改命令,有CPU.内存.硬盘.网络.系统管理等命令.但本文不打算介绍生僻命令,也不介绍各个linux发行版下的特有命令,且以后会持续更新. 说明,我是在一个Centos 6.4 64位的虚拟机系统进行测试.本文介绍的命令都会在此Centos下运行验证(也有部分命令会在我的suse/ubuntu系统里测试的,会做特明说明),但运行结果就不再列出了. 硬件篇 CPU相关 lscpu #查看的是cpu的统计信息. cat /pro