linux:编写自己的ls命令

【命令功能】
linux系统中ls -l命令可以获得某个目录下文件的具体信息,比如:
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$ ls -l
total 20
-rw-r--r-- 1 gaolu gaolu 2578 2009-03-08 02:10 gao.lu.c
-rw-r--r-- 1 gaolu gaolu 2577 2009-03-08 02:07 gao.lu.c~
-rwxr-xr-x 1 gaolu gaolu 9675 2009-03-08 02:12 ls.o
-rwxr--r-- 1 gaolu gaolu    0 2009-03-08 01:50 test1
-rw-r--r-- 1 gaolu gaolu    0 2009-03-08 01:50 test2
-rw-r--r-- 1 gaolu gaolu    0 2009-03-08 01:50 test3
-rw-r--r-- 1 gaolu gaolu    0 2009-03-08 01:51 test4
 
系统版本不同,显示的内容可能略有差别,主要包括几项:文件所在的inode值,权限信息,用户主和所属的组,最后修改日期,文件名,链接数等等。
 
【模块划分】
文件的这些基本信息都可以通过stat函数获得,因此只要可以获得某个目录下面的所有文件信息,再依次调用stat函数得到每个文件的信息,就可以实现ls -l命令的基本功能了。
 
结构如下:
                                                                       ------获得目录下所有文件列表                                   
                                                                    |
                        --目录文件列表获得模块-
                        |                                        |
模块划分------                                            ------将文件列表存入链表
                        |                              -----------遍历链表
                        --信息输出模块--|
                                                        |
                                                        -------对每个文件调用stat获得信息并打印
 
【主要函数】
(1)DIR* opendir(const char *name)
功能:打开name指定的目录,返回指针,失败返回NULL.
相关头文件:
sys/types.h
dirent.h
(2)struct dirent* readdir(DIR* dir) 
功能:获得某个打开目录下的具体内容
相关头文件:
sys/types.h
dirent.h
 
【代码实现】
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
//用于保存文件或者目录的名称
typedef struct dir_link{
 char d_name[256];
 struct dir_link * next;
}dirlink;
//保存单个文件的具体信息,方便输出
typedef struct item_info{
 unsigned long inode;
 char permission[11];
 int owner;
 int group;
 off_t size;
 time_t mod_time;
 char name[256];
}info;
 
dirlink* get_dir_detail(char* dirname)
{
 DIR* dir;
 struct dirent* drt;
 dirlink* head_node =NULL;
 dirlink* cur_node = NULL;
 dirlink* next_node = NULL;
 dir = opendir(dirname);  //打开指定目录
 if(NULL == dir)
 {
  perror("Can't open the directroy.");
  return NULL;
 }
 while((drt = readdir(dir)) != NULL)
 {
  if((strcmp(drt->d_name,".")==0)||(strcmp(drt->d_name,"..")==0))
  {
   continue;    //忽略.目录和..目录
  }
  next_node = (dirlink*)malloc(sizeof(dirlink));
  if(NULL == head_node)
  {
   head_node = next_node;   //首节点
  }
  else
  {
   cur_node->next = next_node;
  }
  cur_node = next_node;
  strcpy(cur_node->d_name,drt->d_name);
 }
 cur_node->next = NULL;    //最后一个节点
 closedir(dir);
 return head_node;   //返回链表头指针
}
void print_file_info(dirlink* head_node)
{
 struct stat file_stat;
 dirlink* cur_node = head_node;
 info file_info;
 static char* perm[] = {"---","--x","-w-","-wx","r--","r-x","rw-","rwx"};
 
 while(NULL != cur_node)   //遍历链表
 {
  int i = 3;
  int j = 0;
  unsigned int mask = 0700;
  if(stat(cur_node->d_name,&file_stat) == -1)
  {
   perror("Can't get the information of the file.\n");
   cur_node = cur_node->next;
   continue;
  } 
  if(S_ISREG(file_stat.st_mode))    //是普通文件
  {
   file_info.permission[0]='-';
  }
  if(S_ISDIR(file_stat.st_mode))    //是目录
  {
   file_info.permission[0]='d';
  }
//通过移位运算计算具体权限
  while(i>0)
  {
   file_info.permission[1+j*3] = perm[(file_stat.st_mode & mask)>>(i-1)*3][0];
   file_info.permission[2+j*3] = perm[(file_stat.st_mode & mask)>>(i-1)*3][1];
   file_info.permission[3+j*3] = perm[(file_stat.st_mode & mask)>>(i-1)*3][2];
   i--;
   j++;
   mask>>=3;
  }
//获得其他信息
  file_info.permission[10] = '\0';
  file_info.owner = file_stat.st_uid;
  file_info.group = file_stat.st_gid;
  file_info.mod_time = file_stat.st_atime;
  file_info.size = file_stat.st_size;
  file_info.inode = file_stat.st_ino;
  strcpy(file_info.name,cur_node->d_name);
//打印信息
  printf("%u ",file_info.inode);
  printf("%s ",file_info.permission);
  printf("%d ",file_info.owner);
  printf("%d ",file_info.group);
  printf("%u ",file_info.size);
  printf("%s ",ctime(&file_info.mod_time));
  printf("%s \n",file_info.name);
  
  cur_node = cur_node->next;
 }
}
int main(int argc,char* argv[])
{
 dirlink* head = get_dir_detail(".");   //输入参数为当前目录
 print_file_info(head);
 return 0;
}
 
【运行结果】
gaolu@gaolu-desktop:~/test_folder$ gcc -o ls.o gao.lu.c
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$ ./ls.o
3771 -rwxr--r-- 1000 1000 0 Sun Mar  8 01:59:13 2009
 test1
3773 -rw-r--r-- 1000 1000 0 Sun Mar  8 02:06:26 2009
 test3
3772 -rw-r--r-- 1000 1000 0 Sun Mar  8 02:06:26 2009
 test2
3822 -rw-r--r-- 1000 1000 2578 Sun Mar  8 02:10:43 2009
 gao.lu.c
3785 -rwxr-xr-x 1000 1000 9675 Sun Mar  8 02:12:58 2009
 ls.o
3774 -rw-r--r-- 1000 1000 0 Sun Mar  8 02:06:26 2009
 test4
3770 -rw-r--r-- 1000 1000 2577 Sun Mar  8 02:07:23 2009
 gao.lu.c~
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
 
【-_-! 改了半宿的bug...】

你可能感兴趣的:(代码,linux,实现,休闲,ls命令)