基于 GNU/Linux 操作系统的以 C语言 实现 ls命令 的部分功能

目标

  • 实现 ls 的 -a、-l、-R、-t、-r、-i、-s 参数,并允许这些参数任意组合.
  • -R 需要通对 / 的遍历测试
  • 界面美观(输出对齐、与颜色显示等)
  • 无资源与内存泄露

准备

书籍阅读

  • <<Linux/Unix系统编程手册(上)>>
    – 2, 3略读
    – 4, 5.2-5.5, 15, 18 重点
  • <<Unix_Linux编程实践教程>>
    – 1, 2, 3

好文

实现

具体目标

  1. 命令行选项
  • -a : 显示所有文件及目录 (包括. 开头的隐藏文件)
  • -l : 除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出
  • -R : 迭代显示目录下所有的子目录
  • -t : sort by modification time, newest first
  • -r : 将文件以相反次序显示(原定依英文字母次序)
  • -i : 打印每个文件的index值
  • -s : 显示以块为单位的文件大小
  1. 界面
  • 对齐
  • 颜色
  1. 高性能
  • 无内存与资源泄露

BASE

  • 文件函数
  • ls的实现只需考虑文件和目录两种情况,无需考虑驱动器或分区(位于不同分区的目录通过文件树无缝连接到一起)
  • 目录是一种特殊的文件,它的内容是 文件 和 目录的名字
  • 文件名包含在目录中,而文件信息可用stat()函数得到
    在这里插入图片描述
    (上图中成员变量不含未被ls -l所使用的变量,并非stat.h的全部成员变量)
  • 字域掩码

ls的功能

  • 列出目录的内容
  • 显示文件的信息

基于上述两点,我们可以先编写一个最基本的ls程序,只要能list就行,后续再实现各种进阶目标

ls所需头文件:
<stdio.h>
<stdlib.h>(提供exit函数)
<sys/types.h>(基本系统数据类型)
<dirent.h>(用于目录操作)
ls的算法:
mian(){
   
	opendir
	while(readdir){
   
		print d_name
	}
	closedir
}
SHOW ME THE CODE
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<stdlib.h>

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);//print环节
        }
    }
}

void do_ls(char dirname[])
{
   
    DIR *dir_ptr;//文件夹指针
    struct dirent *direntp;//存放文件夹目录内容

    if((dir_ptr = opendir(dirname)) == NULL){
   //open环节
        fprintf(stderr, "ls1: Cannot open %s\n",dirname);//打开失败
    }else{
   
        while((direntp = readdir(dir_ptr)) != NULL){
   //while(readdir)
            printf("%s\n",direntp -> d_name);//d_name:当前遍历子项的文件名,限制长度为256,包括字符串终止符’\0’
        }
        int flag;
        if(( flag = closedir(dir_ptr)) == -1){
   //close环节
            perror("ls1: Cannot close dir");//关闭失败
            exit(0);
        }
}

效果示例:(基于mintOS)

  • 查看当前目录
    在这里插入图片描述

  • 查看指定目录
    在这里插入图片描述

ls -l 的实现

在以上的基础上,加入:

  • stat函数
  • 掩码判断文件类型(留个坑,有机会就写一篇掩码相关博客)

实现ls -l代码如下

#include<stdio.h>
#include<stdlib.h>
#include<dirent.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<pwd.h>
#include<grp.h>

void do_ls(char[]);//执行ls基本操作
void dostat(char *);//获取文件信息
void show_file_info(char *, struct stat *);//展示从stat获取的信息
void mode_to_letters(int ,char[]);//将模式字段转化为字符
char * uid_to_name(uid_t);//将用户ID转化为字符串
char * gid_to_name(gid_t);//将组ID转化为字符串

int main(int argc, char *argv[])
{
   
    if(argc == 1){
   
        do_ls(".");
    }else{
   
        while(--argc){
   
            printf("%s:\n", * ++argv);
            do_ls(*argv);
        }
    }
}

void do_ls(char dirname[])
//list files in directory called dirname
{
   
    DIR *dir_ptr;
    struct dirent *direntp;
    
    if((dir_ptr = opendir(dirname)) == NULL){
   
        perror("打开目录失败");
        exit(0);
    }else{
   
        while((direntp = readdir(dir_ptr)) != NULL){
   
            dostat(direntp -> d_name);//调用下一函数
        }
        int flag;
        if((flag = closedir(dir_ptr)) == -1){
   
            perror("关闭目录失败");
        }
    }
}

void dostat(char *filename)
{
   
    struct stat info;//存放stat结构体数据的地址
    if(stat(filename, &info) == -1){
   //解析filename,将得到的信息放在info
        perror("获取信息失败");
    }else{
   
        show_file_info(filename,&info);//调用下一函数
    }
}

void show_file_info(char *filename, struct stat *info_p)//此处的info_p就是stat放东西的info位
//display the info about filename
{
   
    char *uid_to_name(), *ctime(), 
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值