高仿linux下的ls -l命令——C语言实现
主要用到的函数可以参考头文件,仅仅支持ls -l这功能,扩展就交给大家了0.0
相关测试图片:


编译 gcc -std=c99 ls_l.c -o ls
运行 ./ls -l
( 请勿在文件结构复杂的目录下执行,程序会挂的!)
话不多说,直接上码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <dirent.h> #define MAX_FILE_NUM 200 //可能还有一些小问题没有解决,功能基本已经实现,如有建议,望大佬赐教 typedef struct LS
{
char mode[]; // 文件的模式
int dir_num; // 是否目录或目录中包含目录的数量
char user[]; // 文件的用户名
char group[]; // 文件的组名
long size; // 文件的字节数
char time[]; // 文件的最后修改时间
char year[]; // 拓展用,年份
char mon[]; // 月份
char hour[]; // 时
char min[]; // 分
int st_mode; // 文件类型和权限
char name[]; // 文件名
}LS; // 获取文件的模式
char* file_mode(mode_t m,char* str)
{
if(S_ISREG(m))
str[] = '-';
else if(S_ISDIR(m))
str[] = 'd';
else if(S_ISCHR(m))
str[] = 'c';
else if(S_ISBLK(m))
str[] = 'b';
else if(S_ISFIFO(m))
str[] = 'q';
else if(S_ISLNK(m))
str[] = 'l';
// else if(S_ISSOCK(m))
// str[0] = 's';
else
str[] = '?'; str[] = '\0'; strcat(str,S_IRUSR&m?"r":"-");
strcat(str,S_IWUSR&m?"w":"-");
strcat(str,S_IXUSR&m?"x":"-"); strcat(str,S_IRGRP&m?"r":"-");
strcat(str,S_IWGRP&m?"w":"-");
strcat(str,S_IXGRP&m?"x":"-"); strcat(str,S_IROTH&m?"r":"-");
strcat(str,S_IWOTH&m?"w":"-");
strcat(str,S_IXOTH&m?"x":"-"); return str;
} // 获取目录的数量
int dir_count(char* path)
{
DIR *dir;
dir = opendir(path);
struct dirent *dirent;
int count = ;
while((dirent = readdir(dir)) != NULL)
{
if(dirent->d_type == )
count++;
}
closedir(dir);
return count;
} // 是否是目录或目录下有目录
int is_dir(struct dirent *dirent)
{
char* a = dirent->d_name;
if(dirent->d_type == )
return ;
if(dirent->d_type == )
{
if(dir_count(a) == )
return ;
else
return dir_count(a);
}
} // 获取用户名
char* file_user(uid_t st_uid,char* str)
{
struct passwd *user;
user = getpwuid(st_uid);
sprintf(str,"%s",user->pw_name);
return str;
} // 获取组名
char* file_group(uid_t st_uid,char* str)
{
struct passwd *user;
user = getpwuid(st_uid);
struct group *grp;
grp = getgrgid(user->pw_gid);
sprintf(str,"%s",grp->gr_name);
return str;
} // 获取文件大小
off_t file_size(struct stat buf)
{
off_t size = buf.st_size;
return size;
} // 获取最后修改时间
char* file_time(time_t mt,char* str)
{
struct tm* t = localtime(&mt);
sprintf(str,"%d月 %02d %02d:%02d",t->tm_mon+,t->tm_mday,t->tm_hour,t->tm_min);
return str;
} // 获取文件的数量
int file_count(char* path)
{
DIR *dir;
dir = opendir(path);
struct dirent *dirent;
int count = ;
while((dirent = readdir(dir)) != NULL)
{
count++;
}
closedir(dir);
return count;
} // 交换
void equal(LS *a,LS *b)
{
strcpy(a->mode,b->mode);
a->dir_num = b->dir_num;
strcpy(a->user,b->user);
strcpy(a->group,b->group);
a->size = b->size;
strcpy(a->time,b->time);
a->st_mode = b->st_mode;
strcpy(a->name,b->name);
} // 排序
void sort(LS *info,int index)
{
LS *temp = (LS*)malloc(sizeof(LS));
for(int i=index-; i>; i--)
{
for(int j=; j<i; j++)
{
if(strcmp(info[i].name,info[j].name)<)
{
equal(temp,&info[i]);
equal(&info[i],&info[j]);
equal(&info[j],temp);
}
}
}
} // 输出结构体
void show_ls(LS *info,int index)
{
for(int i=; i<index; i++)
{
//printf("%d: ",i);
printf("%s \033[0m",info[i].mode);
printf("%d ",info[i].dir_num);
printf("%s ",info[i].user);
printf("%s ",info[i].group);
printf("%5ld ",info[i].size);
printf(" %s ",info[i].time);
//printf("%d ",info[i].st_mode);
if( == info[i].st_mode)
{
// 颜色
printf("\033[34m\033[1m%s\033[0m",info[i].name);
}
else if( == info[i].st_mode)
{
printf("\033[32m\033[1m%s\033[0m",info[i].name);
}
else
{
printf("%s",info[i].name);
}
if(i < index)
printf("\n");
}
//printf("循环结束\n");
} // 创建结构体,赋值
LS *create(struct stat buf,struct dirent *dirent)
{
LS* info = (LS*)malloc(sizeof(LS));
char str[] = {};
//puts(file_mode(buf.st_mode,str));
strcpy(info->mode,file_mode(buf.st_mode,str));
//puts(info->mode);
info->dir_num = is_dir(dirent);
strcpy(info->user,file_user(buf.st_uid,str));
strcpy(info->group,file_group(buf.st_uid,str));
info->size = file_size(buf);
strcpy(info->time,file_time(buf.st_mtime,str));
info->st_mode = buf.st_mode;
strcpy(info->name,dirent->d_name); return info;
} int main(int argc,char* argv[])
{
LS info[MAX_FILE_NUM];
char* l = "-l";
if(argc != )
{
printf("仅支持传入 -l\n");
return ;
}
if(strcmp(argv[],l) != )
{
printf("\"ls:无法识别的选项\"%s\"\n",argv[]);
printf("请尝试执行\"ls --help\"来获取更多信息。\n");
return ;
}
char* a = ".";
char* b = "..";
char* path = malloc();
strcpy(path,"./"); // 只支持当前路径
int count = file_count(path); DIR *dir;
dir = opendir(path);
struct dirent *dirent;
int index = ; // 结构体下标
int blocks = ;
for(int i=; i<count; i++)
{
dirent = readdir(dir);
struct stat buf = {};
if(stat(dirent->d_name,&buf))
{
perror("stat");
return -;
} // 跳过特殊情况
if(strcmp(dirent->d_name,a)== || strcmp(dirent->d_name,b)==)
continue;
blocks += buf.st_blocks;
//printf("%d\n",blocks);
info[index++] = *create(buf,dirent);
}
closedir(dir);
//printf("文件总数:%d\n",index);
//show_ls(info,index); printf("总用量 %d\n",blocks/);
sort(info,index);
show_ls(info,index);
return ;
}
高仿linux下的ls -l命令——C语言实现的更多相关文章
- 实现Linux下的ls -l命令
基本实现了Linux下的ls -l命令,对于不同的文件显示不同的颜色和显示符号链接暂时没有实现: /************************************************** ...
- 模拟linux下的ls -l命令
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h&g ...
- 编程实现Linux下的ls -l
头文件 #ifndef __FUNC_H__ #define __FUNC_H__ #include <stdio.h> #include <stdlib.h> #includ ...
- linux下ls -l命令(即ll命令)查看文件的显示结果分析
在linux下使用“ls -l”或者“ls -al”或者“ll”命令查看文件及目录详情时,shell中会显示出好几列的信息.平时也没怎么注意过,今天忽然心血来潮想了解一下,于是整理了这篇博客,以供参考 ...
- linux下如何使用sftp命令【转】
linux下如何使用sftp命令 from: http://www.cnblogs.com/chen1987lei/archive/2010/11/26/1888391.html sftp 是一个 ...
- linux下find和grep命令详解
在linux下面工作,有些命令能够大大提高效率.本文就向大家介绍find.grep命令,他哥俩可以算是必会的linux命令,我几乎每天都要用到他们.本文结构如下: find命令 find命令的一般形式 ...
- 终端的乐趣--Linux下有趣的终端命令或者工具【转】
转自:https://blog.csdn.net/gatieme/article/details/52144603 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...
- Linux下的一些常用命令(一)
在Linux环境下敲各种命令是再正常不过了,尤其是现在大多少服务器均为Linux系统,但是我又记不住这么多命令,只是偶尔在项目做完发布到服务器上的时候会涉及到,所以在网上找了一些命令,在此记录一下~ ...
- 实现linux下的ls
实现linux下的ls ls的使用 ls -a 列出文件下所有的文件,包括以"."开头的隐藏文件(linux下文件隐藏文件是以.开头的,如果存在..代表存在着父目录). ls -l ...
随机推荐
- 转载:Databricks孟祥瑞:ALS 在 Spark MLlib 中的实现
Databricks孟祥瑞:ALS 在 Spark MLlib 中的实现 发表于2015-05-07 21:58| 10255次阅读| 来源<程序员>电子刊| 9 条评论| 作者孟祥瑞 大 ...
- hhhhh我又双叒进步啦!
虽然说从今天开始短暂的暑假一周假期正式开始,然而第一天我就深感在家有多无聊...所以说还是整天待在学校好丫! 不过,就算在家, 勤奋好学的 我也要认真做题!今天就一鼓作气地把排名刷到了第 50 名!! ...
- Element源码---初识框架
序言 如果前期直接看源码,你会发现源码越看越看不懂,越看越难,觉得没有办法入手去写,其实首先想要了解项目结构最简单的方法就是通过目录 1.项目理念 2.解析目录 目前想不到更好的办法整理element ...
- URL的作用是什么?它由几部分组成?
URL是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址.互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它 ...
- win10任务栏不显示垃圾的搜狗图标
设置-->时间和语言-->拼写键盘和键入设置-->高级键盘设置-->语言栏选项-->语言栏-->勾选隐藏-->同时去掉在任务栏显示其他语言图标
- 【BIRT】汉化设计器
点击下面文字即可下载汉化包 birt汉化_plugins.rar 下载完成之后,解压: 将上述文件copy到目录../eclipse/plugins/下即可 文件复制后,重新启动eclipse,则已经 ...
- session与cookie之间的关系
一.客户端与服务端请求响应的关系 USER(客户端) 请求 tomcat(服务器), 属于HTTP请求.http请求是无状态的,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户 ...
- Python 拼接字符串的几种方式
在学习Python(3x)的过程中,在拼接字符串的时候遇到了些问题,所以抽点时间整理一下Python 拼接字符串的几种方式. 方式1,使用加号(+)连接,使用加号连接各个变量或者元素必须是字符串类型( ...
- ASP.NET MVC下如何返回图片
方式一: 首先,我们应当从控制器入手,控制器一般不都是return View的吗?那怎么返回图片? 当然,Controller类也没有return Image 的,上次我们的例子是返回JSON,其实我 ...
- k8s记录-helm部署(九)
helm 组件配置在 192.168.0.1 192.168.0.2 192.168.0.3 app 用户下操作tar xvf helm-v2.14.3-linux-amd64.tar.gzsudo ...