手动实现linux文件命令 ls -a -l

先看效果

Ubuntu 18.04 ZSH

ls

在这里插入图片描述

ls -a

在这里插入图片描述

ls -l

稍有不同
在这里插入图片描述

ls -al

稍有不同
在这里插入图片描述

代码实现

源码

/*************************************************************************
    > File Name: myls.c
    > Author: 
    > Mail: 
    > Created Time: Wed 25 Aug 2021 12:06:33 AM CST
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<dirent.h>
#include<sys/types.h>
#include<pwd.h>
#include<grp.h>
#include<time.h>
#include<unistd.h>
#define CNT 256

//颜色宏定义
#define COLOR_HL(a, b) "\033[1;" #b "m" a "\033[0m"
#define GREEN_HL(a) COLOR_HL(a,32)
#define BLUE_HL(a) COLOR_HL(a,34)

#define Type(a) _Generic((a),\
    int : "%d", \
    double : "%lf", \
    float : "%f", \
    long long : "%lld", \
    const char* : "%s", \
    char * : "%s" \
)

#define P(a, color) {\
    char str_temp[100];\
    sprintf(str_temp, color("%s"), Type(a));\
    printf(str_temp, a);\
}

#define SWAP(a, b) {\
    __typeof(a) temp = a;\
    a = b;\
    b = temp;\
}

// 输出结构
typedef struct name_list{
    char type;
    char access[CNT];
    int link_num;
    char owner[CNT];
    char group[CNT];
    int size;
    char time[CNT];
    char name[CNT];
} name_list;

int file_name(DIR *fp, char *path, struct name_list name[CNT], int all_flag);
void str_sort(struct name_list name[CNT], int index[CNT], int cnt);
char *time_change(char *time);
void show(struct name_list name[CNT], int index[CNT], int cnt);
void show_l(struct name_list name[CNT], int index[CNT], int cnt);
void swap(struct name_list n1, struct name_list n2);
void get_access_permission(struct stat buf, char* res);
char get_file_type(struct stat buf);

int main(int argc, char *argv[]) {
    DIR *fp;
    struct name_list name[CNT];
    // index数组记录排序后的顺序,避免直接对结构体数组name更改
    int index[CNT];
    int cnt, c;
    // 两个bool记录-a 和 -l选项
    int all_flag = 0, list_flag = 0;
    char file_path[CNT] = "./";
    //getopt 函数解析命令行获取-a -l参数
    while ((c = getopt(argc, argv, "al")) != -1) {
        switch(c) {
            case 'a':
                all_flag = 1;break;
            case 'l':
                list_flag = 1;break;
            default:
                strcpy(file_path, optarg);                    
        }
    }
    fp = opendir(file_path);
    cnt = file_name(fp, file_path, name, all_flag);
    for (int i = 0; i < cnt; i++){
        index[i] = i;
    }
    str_sort(name, index, cnt);
    if (list_flag == 1) {
        show_l(name, index, cnt);
    }
    else {
        show(name, index, cnt);
    }
    return 0;
}

// -l 的打印函数
void show_l(struct name_list name[CNT], int index[CNT], int cnt){
    printf("%d\n", cnt);
    for (int i = 0; i < cnt; i++) {
        int temp = index[i];
        printf("%c%s %3d %s %s %5d %s ", name[temp].type, name[temp].access, name[temp].link_num, 
               name[temp].owner, name[temp].group, name[temp].size, name[temp].time);
        if (name[temp].type == 'd'){
            P(name[temp].name, BLUE_HL);
            printf("\n");
        }
        else if (name[temp].access[8] == 'x') { 
            P(name[temp].name, GREEN_HL);
            printf("\n");
        }
        else {
            printf("%s\n", name[temp].name);
        }
    }
}

//非-l的打印函数
void show(struct name_list name[CNT], int index[CNT], int cnt){
    for (int i = 0; i < cnt; i++) {
        int temp = index[i];
        i && printf("  ");
        if (name[temp].type == 'd'){
            P(name[temp].name, BLUE_HL);
        }
        else if (name[temp].access[8] == 'x') { 
            P(name[temp].name, GREEN_HL);
        }
        else {
            printf("%s", name[temp].name);
        }
    }
    printf("\n");
}

// 解析文件函数
int file_name(DIR *fp, char *path, struct name_list name[CNT], int all_flag) {
    int cnt = 0;
    struct dirent *p;
    while ((p = readdir(fp)) != NULL) {
        if ((strncmp(p->d_name, ".", 1) == 0 || strncmp(p->d_name, "..", 2) ==0) && !all_flag) {
            continue;
        }
        strcat(name[cnt].name, p->d_name);
        struct stat buf;
        lstat(p->d_name, &buf);
        get_access_permission(buf, name[cnt].access);
        name[cnt].type = get_file_type(buf);
        name[cnt].link_num = buf.st_nlink;
        strcat(name[cnt].owner, getpwuid(buf.st_uid)->pw_name);
        strcat(name[cnt].group, getgrgid(buf.st_gid)->gr_name);
        struct tm *ptime;
        name[cnt].size = buf.st_size;
        ptime = localtime(&(buf.st_mtime));
        sprintf(name[cnt].time, "%d-%d-%d %2d:%2d", ptime->tm_year + 1900, ptime->tm_mon, ptime->tm_mday,
               ptime->tm_hour, ptime->tm_min);
        cnt++;    
    }
    closedir(fp);
    return cnt;
}

//获取文件权限
void get_access_permission(struct stat buf, char* res){
    strcat(res,(S_IRUSR & buf.st_mode) ? "r": "-");
    strcat(res,(S_IWUSR & buf.st_mode) ? "w": "-");
    strcat(res,(S_IXUSR & buf.st_mode) ? "x": "-");
    strcat(res,(S_IRGRP & buf.st_mode) ? "r": "-");
    strcat(res,(S_IWGRP & buf.st_mode) ? "w": "-");
    strcat(res,(S_IXGRP & buf.st_mode) ? "x": "-");
    strcat(res,(S_IROTH & buf.st_mode) ? "r": "-");
    strcat(res,(S_IWOTH & buf.st_mode) ? "w": "-");
    strcat(res,(S_IXOTH & buf.st_mode) ? "x": "-");
}

// 获取文件类型
char get_file_type(struct stat buf){
    if(S_ISREG(buf.st_mode)){
        return '-';        
    }
    else if(S_ISDIR(buf.st_mode)){
        return 'd';        
    }
    else if(S_ISCHR(buf.st_mode)){
        return 'c';        
    }
    else if(S_ISBLK(buf.st_mode)){
        return 'b';        
    }
    else if(S_ISFIFO(buf.st_mode)){
        return 'p';        
    }
    else if(S_ISLNK(buf.st_mode)){
        return 'l';        
    }
    else if(S_ISSOCK(buf.st_mode)){
        return 's';
    }
}

//简单的冒泡排序,
void str_sort(struct name_list name[CNT], int index[CNT], int cnt) {
    for (int i = 1; i < cnt; i++){
        for (int j = 0; j < cnt - i; j++){
            if (strcmp(name[index[j]].name, name[index[j + 1]].name) > 0) {
                SWAP(index[j], index[j + 1]);
            }
        }
    } 
}

生成可执行文件

gcc myls.c -o myls
cp myls /usr/bin/myls
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量化就是探索生活

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值