Linux基础—ls功能的简单实现

简单的ls实现,首先,我们需要遍历参数目录下的各个文件,再根据文件相应的性质,读取文件的权限,用户组,用户名,大小,最后一次访问的时间,再根据文件名排序后依次显示。

  具体的函数声明如下:


1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <string.h>

4 #include <sys/stat.h>

5 #include <fcntl.h>

6 #include <unistd.h>

7 #include <dirent.h>

8 #include <sys/types.h>

9 #include <pwd.h>

10 #include <grp.h>

11 #include <time.h>

12 #define CNT 256

13 int file_name(DIR *fp, char *path, char name[][CNT]);

14 void str_sort(char name[][CNT], int cnt);

15 void mode_to_char(mode_t mode, char *buf);

16 char *time_change(char *time);

17 void show(char name[][CNT], int cnt);

  目录的遍历,我们需要知道目录下读取到的文件个数,所以需要返回相应的int型值。

  目录的遍历实现如下:


1intfile_name(DIR*fp,char*path,charname[][CNT])

2{

3intcnt=0;

4structdirent*p;

5while((p=readdir(fp))!=NULL)

6{

7if(strncmp(p->d_name,".",1)==0||strncmp(p->d_name,"..",2)==0)

8continue;

9strcpy(name[cnt],path);

10strcat(name[cnt],"/");

11strcat(name[cnt],p->d_name);

12cnt++;

13}

14closedir(fp);

15returncnt;

16}

  然后我们需要了解文件的权限,文件权限保存在相对应的参数char *buf中。

文件权限的解读实现如下:


1 void mode_to_char (mode_t mode, char *buf)

2 {

3     memset(buf, '-', 10);

4     if(S_ISDIR(mode))

5         buf[0] = 'd';

6     if(mode & S_IRUSR)

7         buf[1] = 'r';

8     if(mode & S_IWUSR)

9         buf[2] = 'w';

10     if(mode & S_IXUSR)

11         buf[3] = 'x';

12     if(mode & S_IRGRP)

13         buf[4] = 'r';

14     if(mode & S_IWGRP)

15         buf[5] = 'w';

16     if(mode & S_IXGRP)

17         buf[6] = 'x';

18     if(mode & S_IROTH)

19         buf[7] = 'r';

20     if(mode & S_IWOTH)

21         buf[8] = 'w';

22     if(mode & S_IXOTH)

23         buf[9] = 'x';

24 }

  想应的,时间的显示不需要那么精确,所以我们应适当的缩短时间精确度。

  时间的显示实现如下:

  1 char *time_change(char *time)

  2 {

  3     int index = strlen(time) - 1;

  4     for(; time[index] != ':'; index --);

  5     time[index] = '\0';

  6     return time + 4;

  7 }

  然后,我们需要根据文件名称按照字典序排序。

  排序的实现如下:


1 void str_sort(char name[][CNT], int cnt)

2 {

3     int index, pos;

4     char str[CNT];

5     for(pos = 1; pos < cnt; pos ++)

6     {

7         strcpy(str, name[pos]);

8         for(index = pos - 1; index >= 0; index --)

9             if(strcmp(name[index], str) > 0)

10                 strcpy(name[index + 1], name[index]);

11             else

12                 break;

13         strcpy(name[index + 1], str);

14     }

15 }

 最后,我们在编写一个简单的show()函数,来显示各个文件的信息。

  show函数实现如下:


1 void show(char name[][CNT], int cnt)

2 {

3     int index;

4     char mode[10];

5     char *str;

6     struct stat buf;

7     for(index = 0; index < cnt; index ++)

8     {

9         memset(&buf, 0, sizeof(buf));

10         if(stat(name[index], &buf) == -1)

11         {

12             printf("stat error!!\n");

13             exit(1);

14         }

15         mode_to_char(buf.st_mode, mode);

16         str = ctime(&buf.st_atime);

17         str = time_change(str);

18         int i;

19         for(i = strlen(name[index]) - 1; name[index][i] != '/'; i --);

20         i++;

21         printf("%10s.%2d %5s %5s%5d%13s %s\n", mode, buf.st_nlink, getpwuid(buf.st_uid)->pw_name, getgrgid(buf.st_gid)->gr_name, buf.st_size, str, name[index] + i);

22     }

23 }

  这里需要注意:

  getpwuid()返回的不是我们要的用户名,我们需要的是该结构体中的一个变量——pw_name,同样的getgrid()也应做相应的转换。

  测试代码如下:


1 #include "head.h"

2 int main(int argc, char *argv[])

3 {

4     DIR *fp;

5     char name[CNT][CNT];

6     int cnt;

7     fp = opendir(argv[1]);

8     if(fp == NULL)

9     {

10         printf("opendir error!!\n");

11         exit(1);

12     }

13     cnt = file_name(fp, argv[1], name);

14     str_sort(name, cnt);

15     show(name, cnt);

16     return 0;

17 }

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-09-15 04:09:31

Linux基础—ls功能的简单实现的相关文章

linux基础之Shell Script入门介绍_linux shell

linux基础之Shell Script 1 Shell Scipt使用指令和基本程序设计结构写成的程序,可以完成复杂的处理流程 1.1 程序书写 复制代码 代码如下: #!/bin/bash# Program:#       This program shows "Hello Wrold" in your screen.# History:# 2013/2/3 on_1y First releasePATH=$PATHexport PATHecho -e "Hello Wo

hi 感恩节——Linux基础教程之mysql和php_linux shell

感恩节.虽然一直没有过这个节日的习惯,但仅仅是听到感恩的消息,都能想到一幅幅画面.愿大家安好! 学习Linux的前言 选择了Linux发行版本,你就会想如何开始学习Linux了. 1.当然是安装Linux了,请上网自行google或者百度,下载redhat linux 5的安装光盘,然后再安装vmware,自行安装 2.多动手,多敲命令.只看书,不实践,一切都是浮云.默认安装redhat 5,启动redhat 5是带有图形界面的,但是图形界面最好少用,对学习Linux不利,一定要尽量用字符界面,

《嵌入式Linux开发实用教程》——第1章 嵌入式Linux基础 1.1 Linux基本命令

第1章 嵌入式Linux基础 1.1 Linux基本命令 在学习嵌入式Linux开发的过程中,将经常使用到Linux的操作命令.实际上,Linux系统中的命令也是为实现特定的功能而编写的,而且绝大数的命令是用C语言编写的.有些实用性强的程序被广泛使用和传播,逐渐地演变成Linux的标准命令.但是Linux的操作命令繁多,本节将在U-Boot.Linux移植过程中常用到的Linux操作命令罗列出来进行讲解,为后续的学习做良好的铺垫.读者不要认为这是Linux简单命令则不屑一顾,嵌入式Linux学习

Linux基础命令介绍十五:推陈出新

本文介绍ip.ss.journalctl和firewall-cmd,它们旨在代替linux中原有的一些命令或服务. 1.ip ip [OPTIONS] OBJECT COMMAND  ip是iproute2软件包里面的一个强大的网络配置工具,它能够替代一些传统的网络管理工具,例如ifconfig.route等,使用权限为超级用户. OPTIONS是修改ip行为或改变其输出的选项. OBJECT是要获取信息的对象.包括: address   表示设备的协议(IPv4或IPv6)地址  link  

linux 基础学习之三:bash shell初识 上

1·.bash shell的功能 • 命令编修能力(类似 DOS 的 doskey 功能): 只要在指令列按『上下键』就可以找到前一个输入的指令!而在很多 distribution 里头,预设的指令记忆功能可以到达 1000 个!也就是说, 你曾经下达过的指令都被记录下来了,记录的档案在你的家目录内的 .bash_history!不过,需要留意的是, ~/.bash_history 记录的是前一次登入以前所执行过的指令, 而至于这一次登入所执行的指令都被暂存在暂内存中,当您成功的注销系统后,该指

《Linux C编程从入门到精通》一第1章 Linux基础1.1 Linux的起源、发展和分类

第1章 Linux基础 Linux C编程从入门到精通 Linux是一套免费使用和自由传播的类UNIX操作系统,它已发展成为现今世界上最流行的一种操作系统.Linux不仅仅能在PC机上运行,随着嵌入式系统的发展,它已经被广泛地应用于各种场合. 1.1 Linux的起源.发展和分类 Linux C编程从入门到精通 Linux从1991年问世到现在已经有20多年的历史,它从一个架构简单的系统内核发展到了现在结构完整.功能丰富的多版本操作系统,本小节将介绍其起源发展和分类. 1.1.1 Linux的起

《嵌入式 Linux应用程序开发标准教程(第2版)》——1.1 嵌入式Linux基础

1.1 嵌入式Linux基础 嵌入式 Linux应用程序开发标准教程(第2版) 自由开源软件在嵌入式应用上受到青睐,Linux日益成为主流的嵌入式操作系统之一.随着MOTOROLA手机A760.IBM智能型手表WatchPad.SharpPDA Zaurus等一款款高性能"智能数码产品"的出现,以及Motorola.Samsung.MontaVista.Philips.Nokia.IBM.SUN等众多国际顶级巨头的加入,嵌入式Linux的队伍越来越庞大了.目前,国外不少大学.研究机构和

Linux基础命令大全(笔记一)_Linux

很多刚开始学习linux的朋友,肯定要接触linux肯定要先学习linux常用命令,最近整理了一下.具体如下: 1.Linux启动等级[ linit  n ] 0-系统停机状态 1-单用户工作状态 2-多用户状态(没有NFS) 3-多用户状态(有NFS) 4-系统未使用,留给用户 5-图形界面 6-系统正常关闭并重新启动  命令 与文件.目录相关的命令­­ ls[列出目录] ls -L    //d开头目录,-开头文件,竖着列 ls –m   //横着列 ls –R   //树状结构列 //-.

C基础 mariadb处理的简单实例_C 语言

引言 MariaDB 是一款灰常不错开源数据库. 这里直接用它来解决业务问题. 业务需求: 现在数据库中表示按照天分表的. 突然我们需要按照月来处理数据. 例如输入一个玩家id, 查找这个玩家这个月内看了一件事几次. 我们先搭建一个环境. 操作系统: Linux version 4.4.0-22-generic (buildd@lgw01-41) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #40-Ubuntu SMP Thu M