Chinaunix首页 | 论坛 | 博客
  • 博客访问: 566897
  • 博文数量: 109
  • 博客积分: 2300
  • 博客等级: 大尉
  • 技术积分: 810
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-02 13:11
文章分类

全部博文(109)

文章存档

2012年(1)

2011年(17)

2010年(62)

2009年(29)

我的朋友

分类: LINUX

2009-10-17 19:42:56

如何用C实现linux下的ls命令

作者:david
出处:
类型:原创DIY进阶教程



首先我讲一下写这篇东西的目的。我觉得对于很多linux新手。尤其是自学的同学。最好的学习的方法就是通过具体的例子。通过一个实践的例子,在学习相关的知识点的同时,就把它们应用到这例子中。这样不仅知道了原理。也知道了怎么去应用。下面就开始用一个常用的命令”ls”开始。所有的东西都是从最基本的原理开始。一步步来教你怎么实践出一个命令

(一)ls命令简单介绍
第一步当然是要明白ls究竟是做什么的。如果你要做一个东西却不知道要用来干嘛。会不会很搞笑?所以下面就简单的介绍ls命令的作用和怎么使用

1.Ls可以列出文件名和文件的属性
在命令行输入ls:


ls 命令.jpg


Ls的默认动作是找出当前所有文件的文件名。按字典排序后输出。
Ls还能显示其他的信息。如果加上-l就会列出每个文件的详细信息。也叫ls的长格式:

ls -l命令.jpg



2.        列出指定目录或文件的信息
Linux系统中会有很多目录。每个目录中又会有很多文件。如果要列出一个非当前目录的内容或者是一个特定文件的信息,则需要在参数中给出目录名或文件名。如:
ls /tmp //列出/tmp目录中各文件的文件名
ls – docs //列出docs目录中各文件的属性
ls *.c //列出当前目录下与*.c匹配的文件,即当前目录下所有以.c为后缀的文件

3.        经常用到的命令行选项
ls -l 在前面已经提到过,-l就是输出文件详细的信息。也叫长格式;
ls -a 列出的内容包含以“.“开头的让文件,即所谓有隐藏文件
ls –lu 显示最后访问时间
ls –t 输出时按时间排序
ls –F 显示文件类型

ls 命令的参数选项非常多,大多也可以组合使用。所以还是比较复杂的。所以我们第一步就只实现它最基本的功能:列出当前目录下的所有文件或子目录。在后续帖子中再实现别的功能。

(二)学习必备的知识

既然是列出文件和目录,那么肯定是和linux文件系统有关系的,所以要写ls命令,至少要对文件系统的基本原理有一定的了解。为了不至于使这个帖子内容过于复杂,我把这方面的知识介绍单独开了一个帖子:
DIR命令ls基础篇1:Linux 文件系统详解

如果你对这些已经有所了解。就会知道linux下的文件都是以/为根目录的树型结构,虽然linux下有普通文件、目录文件、链接文件、设备文件、管道文件这几种类型。但链接文件、设备文件、管道文件都可以当做普通文件看待,那实际也就只要区分普通文件和目录文件这两种了。而目录文件的内容就是它所包含所有文件和子目录的一个列表,所以只要打开目录文件并读取对应目录块里的那个列表数据,就可以得到些目录下所有文件和子目录的名称了。其实这个流程简单,就是:打开目录->读取内容->显示文件名称->关闭打开的目录。用伪代码流程表示如下:
Mani(){
Opendir
While(readdir)
Print d_name
Closedir;
}


那么现在的问题是用什么函数去打开并读目录呢?又是怎么样来读出数据呢?这里介绍是的opendir 和readdir,但是可能对于一些新手来说,就算知道了函数名称也不一定知道怎么用。别急,下一步就是教你怎么去查相应函数的帮助资料。
linux下查看帮助手册的命令是man,关于man的详细介绍在这个帖子里我有详细介绍: 如果对这方面还不是很清楚的可以先去学习一下。
好了,如果你已经明白man的用法,我们就开始查看opendir和readdir的用法
我们在命令行输入:
# man 3 opendir

图4-1 opendir.jpg

解释:
#include
#include
这是必须包含的头文件
DIR *opendir(const char *name); 是函数原型;其中DIR * 表示是返回一个 DIR类型的指针,const char *name 是传入的参数
RETURN VALUE 是对返回值的说明。这里说明了如果有错误就返回NULL
DESCRIPTION: opendir()用来打开参数name指定的目录,并返回DIR * 形态的目录流,DIR 并指向目录流的第一位
图4-2

图4-2 readdir.jpg

  解释:
头文件和opendir一样
函数原型:struct dirent * readdir(DIR * dir);
函数说明  readdir()返回参数dir目录流的下个目录进入点。
Struct dirent这一段是结构说明,基中解释分别下:
d_ino 此目录进入点的inode
d_off 目录文件开头至此目录进入点的位移
d_reclen _name的长度,不包含NULL字符
d_type d_name 所指的文件类型
d_name 文件名

(三)学完成代码

在当前目录创建新文件ls1.c;前输入以下内容

代码:

#include    
#include   
#include   

void do_ls(char []);

main(int ac, char *av[])
{
    if ( ac == 1 )
        do_ls( '.' );
    else
        while ( --ac ){
            printf('%s:\n', *++av );
            do_ls( *av );
        }
}

void do_ls( char dirname[] )
/*
*  list files in directory called dirname
*/
{
    DIR     *dir_ptr;       /* the directory */
    struct dirent   *direntp;       /* each entry    */

    if ( ( dir_ptr = opendir( dirname ) ) == NULL )
        fprintf(stderr,'ls1: cannot open %s\n', dirname);
    else
    {
        while ( ( direntp = readdir( dir_ptr ) ) != NULL )
            printf('%s\n', direntp->d_name );
        closedir(dir_ptr);
    }
}






保存并退出;

(四)怎么编译和运行

编写好代码好就要编译了; linux的常用编译工具就是gcc了
#gcc –o ls1 ls1.c
如图2-3查看当前的文件会发现多了ls1这个文件。这就是编译出来的可执行文件
然后运行此程序:
#./ls1
结果如图4-3


图4-3.jpg


怎么样,是不是觉得非常简单啊!当然了这一过程中最主要的是希望你能从中学习到东西,比如对文件系统的原理有一定的认识;知道用man获取帮助文档等等。
接下来会在此程序的基础上加一些ls命令的选项。具体实现在第二个版本中:
阅读(1471) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~