在Linux上实现自定义的 ls命令

  1. 阅读联机帮助
    在Linux上实现自定义的 ls命令
    文章图片
列出有关文件的信息(默认为当前目录)。如果未指定 -cftuvSUX 或 --sort,则按字母顺序对条目进行排序。
可以看到,ls命令 能够找出当前目录中所有文件的文件名,按字典序排序后输出。
ls命令 还能显示其他信息,如果加上 -l 选项,ls 会列出每个文件的详细信息,也叫 ls的长格式,在 man手册 中可以看到:
在Linux上实现自定义的 ls命令
文章图片

使用长列表格式
现在在我们的终端键入命令:
在Linux上实现自定义的 ls命令
文章图片

通过实验和联机帮助可以知道 ls 做了以下两件事(ls 能判定参数指定的是文件还是目录):
列出目录的内容
显示文件的信息
在正式开始之前,来看一下 Unix 是如何组织磁盘上的文件的。
在Linux上实现自定义的 ls命令
文章图片

大方框表示目录,大方框内的小方框表示文件,目录之间的连线表示目录之间的组织关系。
https://www.doc88.com/p-38773...
  1. ls是如何工作的
    通过联机帮助(过程省略)可以知道,从目录读数据与从文件读数据是类似的, opendir 打开一个目录,readdir 返回目录中的当前项,closedir 关闭一个目录,seekdir、telldir、rewinddir与 lseek 的功能类似。
接下来用 man手册 查询一下 readdir(3) ,可以看到:
在Linux上实现自定义的 ls命令
文章图片

readdir() 函数返回一个指向 dirent 结构的指针,该结构表示 dirp 指向的目录流中的下一个目录条目。它在到达目录流末尾或发生错误时返回 NULL。
也就是说, readdir() 来读取 struct dirent获得目录中的记录。
  1. 如何编写ls
    最初级的ls命令
下面实现了一个最初级的 ls命令
include include include // opendir() readdir() closedir() https://www.doc88.com/p-38773...
void do_ls(char*);
int main(int argc, char* argv[]) {
if (argc == 1) { do_ls("."); } else { while (--argc) { printf("%s:\n", *(++argv)); do_ls(*argv); } }return 0;

}
void do_ls(char dirname[]) {
DIR* dir_ptr; // 记录opendir()后的返回值 struct dirent* direntp; // 记录readdir()后的返回值if ((dir_ptr = opendir(dirname)) == NULL) { fprintf(stderr, "ls1: cannot open %s\n", dirname); } else { while ((direntp = readdir(dir_ptr)) != NULL) { printf("%s\n", direntp->d_name); } closedir(dir_ptr); }

https://www.doc88.com/p-38773...
运行结果:
  1. 改进ls命令
    加入以下功能:
    在Linux上实现自定义的 ls命令
    文章图片

    排序
    解决办法:把所有的文件名读入一个数组,用qsort函数排序
分栏:标准的 ls 输出是分栏排列的,有些以行排列,有些以列排列
解决办法:把文件名读入数组,然后计算出列的宽度和行数
“.”文件:ls 列出了 “.”文件,而标准的 ls只有在给出 -a 选项时才会列出
解决办法:使 ls1 能够接收选项 -a,并在没有 -a 的时候不显示隐藏文件
【在Linux上实现自定义的 ls命令】选项 -l:如果选项中有 -l,标准的 ls会列出文件的详细信息,而 ls1不会
解决办法: 下面讨论

    推荐阅读