前言:
ls命令是linux系统下最常用且最重要的命令,其作用类似于windows的图形界面对用户操作的指引,没有ls命令,便无法知道文件存放位置,存放结构。也就无法对一切皆文件的linux进行准确的操作。
正文:
一、ls命令解析(分析)
ls命令及其参数使用见独立文章,此处主要代码实现ls -l -a -al操作
1、-l 参数是表示输出当前路径(目录)下的文件(隐藏文件除外)
2、-a参数是表示输出当前路径下的所有类型文件(含隐藏文件)
3、-al参数是表示输出当前路径下的所有文件的所有信息,包含文件属性,文件权限,文件属主,文件组用户,文件长度,最后一次修改时间,文件名
二、整体框架思路(ls命令实现的功能比较简单,其实也没什么框架)
1、 ls主要就是命令解析,此处可利用主函数带入的参数作为命令 封装一个函数进行解析,此处由于含有指令的组合,所以以每个指令作为契合条件(例strcmp(argv[1],"-a")==0)来设定入口的话会增加很多复杂的指令,所以这里采用位运算对指令进行记录 例如下图指令
int flag(char *argv[])
{
int flag=0;
if(argv[1]==NULL)
{
return flag;
}
int len=strlen(argv[1])//这里假设指令下标为一
char *p=argv[1];
p++;//跨过'-' 把if(*p=='-')这个条件放在函数外作为函数可否调用的判断条件为好
while(len)
{
if(*p=='a')
{
flag|=1<<0;
p++;
}
else if(*p=='l')
{
flag|=1<<1;
p++;
}
}
return flag;
}
这种方式用于多种指令组合使用时效果很好,可以避免穷举浪费时间。
2、找寻对应指令对应的库函数
这里主要用到的函数有
a) 获取路径函数
头文件#include<unistd.h>
函数原型:char *getcwd(char *buf,size_t size);函数作用:将当前所处绝对路径(也就是linux文件系统下当前目录)拷贝到buff中 (pwd指令中可用到);
b) 打开目录文件函数,读取目录文件函数,关闭目录文件函数
头文件#include<sys/types.h> #include<dirent.h>
函数原型:DIR *opendir(const char *path) 作用打开一个目录文件 将该文件某些信息存放在DIR结构体中
函数原型:struct dirent*readdir(DIR *dir_handle) 作用将目录中所有文件遍历一遍(需要重复读取,结构体中有记录当前读取位置的参数)
函数原型:int close(DIR *dir) 作用顾名思义关闭文件
c) 获取文件属性的库函数
头文件#include<sys/stat.h> #include<unistd.h>
函数原型:int stat(const char *filename,struct stat *buff); 作用将一个文件的相关信息存放在 buff结构体中(结构体中含有什么信息见stat函数单独博客,这里简单说其含有-al指令所需的一些属性)
3、代码中的注意点
a) 不同属性的文件输出有不同颜色,可网上搜寻不同颜色输出方法(此方法我没收录。。。。)
b) stat 获取的文件中的某些属性还另外使用了结构体进行进一步存放,是不能直接输出的 就我写的代码来看遇到了这些:st_gid 组用户信息 其存放在struct group 结构体,里面有组用户名字 st_mtime 最后一次修改的时间信息 其存放在
struct tm 结构体,里面详细记录了天,小时,分,秒等。 还有一个struct passwd是记录使用者信息的(passwd结构体中信息可使用多种方法获取,例如getpwuid(uid获取) getpwnam(filename 获取) 有很多函数 可单独去看看)
c)在获取文件读写权限时需要用stat结构中的st_mode与系统既定宏一个一个进行比对得出
ps:
博主代码能力不强,代码就不贴了,建议自己写完最好再去看源码怎么写,才能很好的提升,否则你只是学会了函数的用法,实际代码能力还是不会得到多大的提升。