Linux系统编程入门 | 模拟实现 ls -l 命令

模拟实现代码

cpp 复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>


int main(int argc, char* argv[]) {
    if (argc < 2) {
        printf("%s filename\n", argv[0]);
        return -1;
    }

    struct stat st;
    int sta = stat(argv[1], &st); // 输入的第一个参数就是文件名称,第二个参数为带回结果的结构体
    if (sta == -1) {
        perror("stat");
        return -1;
    }

    char perms[11] = {0}; // 10个字符的字符串

    // 文件类型
    switch(st.st_mode & __S_IFMT) {
        case __S_IFSOCK:
            perms[0] = 's';
            break;
        case __S_IFLNK:
            perms[0] = 'l';
            break;
        case __S_IFREG:
            perms[0] = '-';
            break;
        case __S_IFBLK:
            perms[0] = 'b';
            break;
        case __S_IFDIR:
            perms[0] = 'd';
            break;
        case __S_IFCHR:
            perms[0] = 'c';
            break;
        case __S_IFIFO:
            perms[0] = 'p';
            break;
        default:
            perms[0] = '?';
    }

    // 使用者权限
    perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-';
    perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-';
    perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-';

    // 同组其他人权限
    perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-';
    perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-';
    perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-';

    // 其他人权限
    perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-';
    perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-';
    perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-';

    // 获取硬链接数
    int linkNum = st.st_nlink;

    // 获取文件所有者名字
    char *uid = getpwuid(st.st_uid)->pw_name;

    // 获取文件所在组
    char *gid = getgrgid(st.st_gid)->gr_name;

    // 获取文件大小(用long int)
    long int size = st.st_size;

    // 获取修改时间
    char *time = ctime(&st.st_mtime); // 传入参数为地址
    // 去掉时间后面的换行符
    char mtime[512] = {0};
    // strlen去掉最后的\0后的长度,注意是strncpy(第三个参数可以指定长度),不是strcpy
    strncpy(mtime, time, strlen(time) - 1); 
    
    char buf[1024];
    sprintf(buf, "%s %d %s %s %ld %s %s", perms, linkNum, uid, gid, size, mtime, argv[1]);

    printf("%s\n", buf);

    return 0;
}

运行结果

1、Linux的文件类型

  1. 普通文件(Regular File):
    常见的文件类型,用于存储数据
    包括文本文件、二进制文件、脚本文件等
    在文件类型标识中用 - 表示
  2. 目录文件(Directory File):
    包含其他文件和目录的容器,用于组织文件系统的结构
    在文件类型标识中用 d 表示
  3. 符号链接文件(Symbolic Link File,软连接):
    类似于Windows中的快捷方式,指向另一个文件或目录
    在文件类型标识中用 l 表示
  4. 字符设备文件(Character Device File):
    提供对字符流设备的访问,例如键盘、鼠标、串口等
    在文件类型标识中用 c 表示
  5. 块设备文件(Block Device File):
    提供对块设备的访问,例如硬盘、光驱等
    在文件类型标识中用 b 表示
  6. 套接字文件(Socket File):
    用于网络通信的文件类型,允许进程之间的双向通信
    在文件类型标识中用 s 表示
  7. 命名管道文件(Named Pipe, FIFO):
    用于进程间通信,允许一个进程写入数据,另一个进程读取数据
    在文件类型标识中用 p 表示

2、man 命令中不同的数字表示手册页的不同部分:

1:用户命令

2:系统调用

3:库函数

4:设备文件和特殊文件

5:文件格式

6:游戏

7:杂项

8:系统管理命令

3、argv0 通常表示的是程序本身的名称

bash 复制代码
./my_program arg1 arg2

argv0 = "./my_program"(表示程序的名称或路径)

argv1 = "arg1"(表示第一个命令行参数)

argv2 = "arg2"(表示第二个命令行参数)

argv0 不一定总是只包含程序的名称,它也可以包含程序的路径,取决于你是如何运行程序的

如果运行命令是 ./my_program,则 argv0 可能是 "./my_program"

如果运行命令是 my_program,则 argv0 可能是 "my_program"

4、time_t 是C/C++编程语言中用于表示时间的数据类型。它定义在头文件 <time.h> 中(C++中是 <ctime>),通常用于表示从1970年1月1日00:00:00 UTC(即"Unix纪元")到当前时间的秒数

相关推荐
Uncertainty!!8 小时前
Ubuntu 22.04 安装超好用中文输入法rime-ice(雾凇拼音)过程记录
linux·ubuntu·中文输入法
ShineWinsu9 小时前
对于Linux:网络基础的解析
linux·网络·面试·udp·笔试·ip·tcp
↘"LYong10 小时前
旧版 CentOS 安装 Docker 完整指南(附国内镜像加速)
linux·运维·docker
Zhang~Ling11 小时前
Vim 多模式详解:命令、插入、底行与插件配置
linux·编辑器·vim
想你依然心痛12 小时前
Linux用户空间与内核空间通信:netlink、ioctl、mmap 零拷贝与性能对比
linux·运维·服务器
做个文艺程序员13 小时前
Linux第12篇:性能监控与瓶颈分析——CPU/内存/IO/网络全维度
linux·运维·网络
HAPPY酷14 小时前
【ROS2】 Conda 环境搭建(命令行版)
linux·运维·python·ubuntu·机器人·conda
hai31524754315 小时前
九章空间几何对照直译法:通用芯片 / 定制专用芯片 编译适配规则
linux·汇编·bash
没头脑的男大15 小时前
CMake学习教学
linux·c++·学习
ton_tom15 小时前
设备驱动程序编程-Linux2.6.10-kdb安装-32位
linux·运维·服务器