模拟实现Linux下命令-ls

本文介绍如何使用C语言实现Linux下的ls -l命令。内容包括理解ls -l命令的功能,分析其显示的七列信息,如文件类型、权限、硬链接数、所有者、所有组、大小和修改时间,并利用库函数获取这些信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先我们对Linux下ls命令已经非常熟悉了,我在这里用C语言仅实现ls -l及ls -l xxx。(仅作练习使用)

首先需要了解ls -l命令都做了那些活动,那么就需要研究以下:
这里写图片描述

我们可以看到有七列主要内容,先来逐个分析:

  1. 文件的类型,此图里所有文件均为目录,所以是d。权限=本用户权限+本组用户权限+其他用户权限
  2. 硬链接数
  3. 文件所输用户名 文件所输用户组名
  4. 文件大小
  5. 时间(这个时间是该文件最后一次被修改的时间)
  6. 文件名
    为了获取以上信息,我们可以使用一个库里的函数来帮助我们。
    这里写图片描述
    可以看到我们所需要的信息都在该函数的结构体被定义。我们可以直接使用这些接口获取。以下附上代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <stdlib.h>
#include <dirent.h>
int file_type(md)
{
    //file type 
    char type[12]="?---------.";
    if((md & S_IFMT)==S_IFREG)  type[0]='-';
    if((md & S_IFMT)==S_IFSOCK) type[0]='s';
    if((md & S_IFMT)==S_IFLNK)  type[0]='l';
    if((md & S_IFMT)==S_IFDIR)  type[0]='d';
    if((md & S_IFMT)==S_IFCHR)  type[0]='c';
    if((md & S_IFMT)==S_IFIFO)  type[0]='p';
    if((md & S_IFMT)==S_IFBLK)  type[0]='b';

    if(md & S_IRUSR)            type[1]='r';
    if(md & S_IWUSR)            type[2]='w';
    if(md & S_IXUSR)            type[3]='x';

    if(md & S_IRGRP)            type[4]='r';
    if(md & S_IWGRP)            type[5]='w';
    if(md & S_IXGRP)            type[6]='x';

    if(md & S_IROTH)            type[7]='r';
    if(md & S_IWOTH)            type[8]='w';
    if(md & S_IXOTH)            type[9]='x';

    printf("%s ",type);
}


int file_ls(char *pd)
{
    struct stat sbuf;

    lstat(pd,&sbuf);

    file_type(sbuf.st_mode);//type

    printf("%d ",sbuf.st_nlink);//hard-link
    //user name and group name 
    struct passwd *pu = getpwuid(sbuf.st_uid);
    if(pu!=NULL)
    {
        printf("%s ",pu->pw_name);
    }
    struct group *gd=getgrgid(sbuf.st_gid);
    if(gd!=NULL)
    {
        printf("%s ",gd->gr_name);
    }
    //file size
    printf("%04d ",sbuf.st_size);

    //file time
    struct tm *tf=localtime(&sbuf.st_mtime);
    printf("%04d/%02d/%02d ",(tf->tm_year+1900),(tf->tm_mon+1),tf->tm_mday);
    printf("%4d:%02d:%02d ",(tf->tm_hour),(tf->tm_min),tf->tm_sec);

    //file name
    printf("%s",pd);

    //symbolic-link
    if(S_ISLNK(sbuf.st_mode))
    {
        printf(" -> ");

    char buf[256]={};
    int len=sizeof(buf);
    readlink(pd,buf,len);
    printf("%s ",buf);
    }
    printf("\n");

}
int main(int argc,char *argv[])
{
    if(argc==1)
    {
    //all file
        DIR* pdir=opendir(".");
        if(pdir==NULL)
        {
            fprintf(stderr,"open dir error!\n");
            return -1;
        }
        struct dirent *pd=NULL;
        while((pd=readdir(pdir))!=NULL)
        {

            //printf("%s\n",pd->d_name);
            file_ls(pd->d_name);
        }
    }
    else if(argc==2)
    {
        file_ls(argv[1]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值