前言
ls可以说是一个linuxer最常用的一个基础命令了,今天学习一下ls背后的逻辑,加深对ls的理解,并试着自己用c语言实现。
一、ls
ls(即list)命令用于列出指定目录下文件名称或当前目录下的文件名称。
语法
ls [-alrtAFR] [name...]
参数
- -a 显示所有文件及目录 (. 开头的隐藏文件也会列出)
- -d 只列出目录(不递归列出目录内的文件)。
- -l 以长格式显示文件和目录信息,包括权限、所有者、大小、创建时间等。
- -r 倒序显示文件和目录。
- -t 将按照修改时间排序,最新的文件在最前面。
- -A 同 -a ,但不列出 “.” (目前目录) 及 “…” (父目录)
- -F 在列出的文件名称后加一符号;例如可执行档则加 “*”, 目录则加 “/”
- -R 递归显示目录中的所有文件和子目录。
实例
➜ / ls
bin boot dev etc home lib lib64 mnt opt proc root run sbin srv sys tmp usr var
二、<dirent.h>
#include <sys/types.h>
#include <dirent.h>
//所需头文件如上
DIR *opendir(const char * name ); //参数为打开目录文件的名称
struct dirent *readdir(DIR *dirp);//struct dirent存储一些文件基本信息(如索引节点号inode、文件名d_name)
int closedir(DIR *dirp);
opendir()与readdir()
==opendir()==函数打开对应目录名称的目录流 ,并返回指向该目录的指针
==readdir()函数用于读取目录,只有一个参数,就是opendir()==返回的结构体指针,或者叫句柄更容易理解些吧。这个函数也返回一个结构体指针 dirent *,指向目录下的文件;==readdir()==每读取一次,文件指针就向下一个文件移动。
DIR结构体定义
struct __dirstream
{
void *__fd;
char *__data;
int __entry_data;
char *__ptr;
int __entry_ptr;
size_t __allocation;
size_t __size;
__libc_lock_define (, __lock)
};
typedef struct __dirstream DIR;
dirent的结构如下定义
struct dirent
{
long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name [NAME_MAX+1];
}
结构体中
-
d_ino存放的是该文件的索引节点号inode;
-
d_off 是文件在目录中的编移,具体是什么意思也不是很明白,很少用到它,
基本上就是用到d_name
-
short d_reclen是这个文件的长度,需要注意的是这里的长度并不是指文件大小,因为大小和长度是两回回事了,你可以用lseek将文件长度移得很长,但大小其实还是那么大。
-
最后一个元素就是我们要的了,文件名称。
三、实现ls
do_ls.c
/*do_ls.c*/
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
int main(){
DIR *pdir=opendir(".");
struct dirent *pdirent=NULL;
if(pdir==NULL){
printf("打开失败");
}
while((pdirent=readdir(pdir))!=NULL){
if(pdirent->d_name[0]=='.'){//跳过隐藏文件
continue;
}
printf("%s ",pdirent->d_name);
}
closedir(pdir);
return 0;
}
成果展示
➜ linux gcc do_ls.c -o do_ls
➜ / /home/earlymor/VSCODE/linux/do_ls
var dev run etc tmp sys proc usr boot home mnt opt root srv bin lib lib64 sbin %
参考
https://blog.csdn.net/dream_allday/article/details/75243818