Linux下用C语言代码模拟实现Linux中查询文件信息命令“ ls -l “

一、 概述

1.1 ls -l 的作用

  • Linux下用于查看对应路径的文件信息(隐藏文件除外),后面跟路径名,不跟则默认查看当前路径下

1.2 文件分布

有四个文件:

  • ls-l.c
  • fun.c
  • ls-l.h
  • makefile

1.3 如何编译执行

  1. 本demo使用的是Makefile,所以把下面所有的文件放在一个文件夹后,在当前路径下的终端输入"make"即可完成编译
  2. 运行的话,Makefile文件中第一行EXE=“内容”,这个内容就是编译生成的可执行文件,在当前路径下的终端输入 “./内容”即可,
  3. 本demo生成的可执行文件名为“ls-l”,所以输入“./ls-l”即可
  4. 同"ls -l",本demo后面可以跟路径,也可以不跟,不跟也是默认查看当前路径下的文件信息

1.4 运行环境

  • 本代码是在Linux----ubuntu18.04中运行的,
  • 如果报错之类的,可以检查一下是不是环境不同导致

二、 直接上代码

ls-l.c

#include "ls-l.h"
int main(int argc, char const *argv[])
{
    char path[128] = "";
    if (argc == 1)
        strcpy(path, ".");
    else
        strcpy(path, argv[1]);
    get_dir_info_by_dirName(path);
    return 0;
}

fun.c

#include "ls-l.h"
//  根据目录名获取目录内容
int get_dir_info_by_dirName(char *s)
{
    char name[128] = "";
    strcpy(name, s);
    //  根据目录名获取目录内容
    DIR *dir_p = opendir(name);
    if (NULL == dir_p)
    {
        ERR_MSG("opendir");
    }
    //  读取目录中的文件
    struct dirent *dir_read_p = NULL;
    struct stat file_st;
    while (1)
    {
        //  读取文件信息
        dir_read_p = readdir(dir_p);
        //  读的为空
        if (NULL == dir_read_p)
        {
            //  如果errno更新了,不是0了,说明有错误
            if (0 != errno)
            {
                ERR_MSG("dir_read");
            }
            break;
        }
        if ('.' == *dir_read_p->d_name)
        {
            continue;
        }

        //  清空文件名,方便重新载入
        bzero(name, sizeof(name));
        //  载入终端输入的路径
        strcpy(name, s);
        //  如果当前路径不是以 '/' 结束,那么追加一个 '/' ,方便识别成目录
        if ('/' != name[strlen(s) - 1])
        {
            strcat(name, "/");
        }

        //  获取当前文件的信息
        //  将文件名追加到目录路径后面,然后获取信息
        file_st = get_file_info(strcat(name, dir_read_p->d_name));

        //  打印文件信息
        print_info(&file_st, dir_read_p->d_name);
    }
    return 0;
}

//  根据文件路径名获取文件信息
struct stat get_file_info(char *name)
{
    //  存放文件信息
    struct stat st;
    //  根据文件名进行绑定
    if (-1 != stat(name, &st))
    {
        return st;
    }
    printf("%s", __FILE__);
    printf("__%d__\n", __LINE__);
    perror("stat");
}

//  获取文件类型
char get_file_type(mode_t m)
{
    switch (m & S_IFMT)
    {
    case S_IFBLK:
        return 'b';
    case S_IFCHR:
        return 'c';
    case S_IFDIR:
        return 'd';
    case S_IFIFO:
        return 'p';
    case S_IFLNK:
        return 'l';
    case S_IFREG:
        return '-';
    case S_IFSOCK:
        return 's';
    default:
        printf("unknown?\n");
        return 0;
    }
}

//  获取文件权限
char *get_file_permission(mode_t *m, char *pre) // mode_t m 是传进来的 st.st_mode
{
    char s[4] = "rwx";
    for (int i = 0; i < 9; i++)
    {
        if (((*m) & (0400 >> i)) == 0)
        {
            pre[i] = '-';
            continue;
        }

        pre[i] = s[i % 3];
    }
    return pre;
}

//  输出信息
void print_info(struct stat *st, char *name)
{
    //  获取文件类型
    char type = get_file_type(st->st_mode);
    //  获取文件权限
    char file_pre[10];
    strcpy(file_pre, get_file_permission(&(st->st_mode), file_pre));
    //  文件硬链接数
    __nlink_t links = st->st_nlink;
    //  获取文件所属用户
    char *u_name = getpwuid(st->st_uid)->pw_name;
    //  获取文件所属组
    char *g_name = getgrgid(st->st_gid)->gr_name;
    //  获取文件大小
    __off_t size = st->st_size;
    //  获取文件时间戳,上次修改时间
    struct tm *t = localtime(&st->st_mtime);
    //  文件名 传进来了
    //  输出
    printf("%c%s %ld %s %s %9ld %2d月 %2d %2d:%02d %s\n",
           type, file_pre, links, u_name, g_name, size,
           t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, name);
}

ls-l.h

#ifndef __LS_L_H__
#define __LS_L_H__

#include <my_head.h>

//  根据目录名获取目录内容
int get_dir_info_by_dirName(char *name);

//  获取文件信息
struct stat get_file_info(char *name);

//  获取文件类型
char get_file_type(mode_t m);

//  获取文件权限
char *get_file_permission(mode_t *m, char *pre); // mode_t m 是传进来的 st.st_mode

//  输出信息
void print_info(struct stat *st, char *name);

#endif

makefile

EXE=ls-l
CC=gcc
CFLAGs=-c

OBJs+=ls-l.o
OBJs+=fun.o

all:$(EXE)

$(EXE):$(OBJs)
	$(CC) $^ -o $@

%.o:%.c
	$(CC) $(CFLAGs) $^ -o $@

clean:
	rm *.o ls-l

三、 运行结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zhk___

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

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

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

打赏作者

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

抵扣说明:

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

余额充值