• 完善ls练习一的功能:

    1. 排序,使用qsort
    2. 分栏,计算宽度和行数
    3. 文件“.”的显示需要由-a选项来选择
    4. 详细信息的显示,-l选项
  • 将stat结构体中的st_mode——16位二进制数转换成10位的字符串
    • 15-12:type
    • 11:suid
    • 10:sgid
    • 9:sticky
    • 8-6:user
    • 5-3:group
    • 2-0:other
  • /etc/passwd文件中包含了用户信息,每行对应一个用户,不同的属性按照分号‘:’隔开。
    • 该文件并未包含所有的用户,在某些网络计算系统中,用户需要登录到任何一台主机上,会有NIS统一地进行身份验证,本地保存的只是一个用户子集。
    • getpwuid系统调用具有较好的可移植性,会从NIS中查找如果在本地找不到的话
  • /etc/group包含了组信息,字段分别为1,组名;2,组密码;3,组ID;4,组成员列表
    • 一个用户可以属于多个组的
    • getgrgid可以用来访问组列表,移植性同上getpwuid
  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <sys/stat.h>
  4 #include <dirent.h>
  5 #include <pwd.h>
  6 #include <grp.h>
  7 #include <string.h>
  8 #include <time.h>
  9
 10 void do_ls(char[]);
 11 void show_file_info(char * filename , struct stat * statbufp );
 12 void mode2letter(int mode , char str[]);
 13 void print_uid2name(uid_t uid );
 14 void print_gid2name(gid_t gid );
 15
 16 int main(int ac , char * av[])
 17 {
 18     if(ac == 1 )
 19     {
 20         do_ls(".");
 21     }
 22     else
 23     {
 24         while( -- ac )
 25         {
 26             printf("%s:\n", * (++ av) );
 27             do_ls(*av);
 28         }
 29     }
 30     return 0 ;
 31 }
 32
 33 void do_ls(char dirname[])
 34 {
 35     DIR * dir_ptr ;
 36     struct dirent * direntp ;
 37     struct stat statbuf ;
 38
 39     if( ( dir_ptr = opendir(dirname) )== NULL )
 40     {
 41         fprintf(stderr, "ls1 can not open %s\n", dirname );
 42     }
 43     else
 44     {
 45         while( ( direntp = readdir(dir_ptr ) ) != NULL )
 46         {
 47             if( stat(direntp -> d_name , &statbuf) == -1 )
 48             {
 49                 perror(direntp -> d_name );
 50             }
 51             else
 52             {
 53                 show_file_info( direntp -> d_name , &statbuf);
 54             }
 55         }
 56     }
 57
 58     closedir(dir_ptr);
 59 }
 60
 61 void show_file_info( char * filename, struct stat * statbufp )
 62 {
 63     char modestr[11]; // include '\0' so 10 + 1 = 11
 64
 65     mode2letter(statbufp -> st_mode , modestr) ;
 66     printf("%s",  modestr );
 67
 68     printf("%4d", (int)statbufp -> st_nlink ) ;
 69     print_uid2name( statbufp -> st_uid ) ;
 70     print_gid2name( statbufp -> st_gid ) ;
 71     printf("%8ld", (long) (statbufp -> st_size) );
 72     printf(" %12.12s", (char*)(4 + ctime(&(statbufp -> st_mtime)) ));
 73     printf(" %s\n",filename );
 74 }
 75
 76 void mode2letter(int mode , char str[])
 77 {
 78     strcpy(str , "----------");
 79
 80     if( S_ISDIR( mode ))
 81         str[0] = 'd' ;
 82     else if( S_ISCHR( mode ))
 83         str[0] = 'c' ;    // else for efficience
 84     else if( S_ISBLK( mode ))
 85         str[0] = 'b' ;
 86
 87     if( mode & S_IRUSR )
 88         str[1] = 'r' ;
 89     if( mode & S_IWUSR )
 90         str[2] = 'w' ;
 91     if(mode & S_IXUSR )
 92         str[3] = 'x' ;
 93
 94     if( mode & S_IRGRP )
 95         str[4] = 'r' ;
 96     if( mode & S_IWGRP )
 97         str[5] = 'w' ;
 98     if( mode & S_IXGRP )
 99         str[6] = 'x' ;
100
101     if( mode & S_IROTH )
102         str[7] = 'r' ;
103     if( mode & S_IWOTH )
104         str[8] = 'w' ;
105     if( mode & S_IXOTH )
106         str[9] = 'x' ;
107 }
108
109 void print_uid2name( uid_t uid )
110 {
111     struct passwd * passwdbufp ;
112
113     if(( passwdbufp = getpwuid(uid)) != (struct passwd *)NULL ) // Except for error
114     {
115         printf( "%-8s" , passwdbufp -> pw_name ) ;
116     }
117     else
118     {
119         printf( "%8d" , uid) ;
120     }
121
122 }
123
124 void print_gid2name(gid_t gid)
125 {
126     struct group * grp_ptr ;
127     if(( grp_ptr = getgrgid(gid)) != (struct group * )NULL )
128     {
129         printf("%-8s" , grp_ptr -> gr_name ) ;
130     }
131     else
132     {
133         printf("%8d" , gid ) ;
134     }
135 }

ls2.c完成了 ls -l 的功能。但是有几点不足之处:

  1. 不显示总数,这个容易解决
  2. 未排序
  3. 不支持参数-a
  4. 假设参数只是目录名
  5. 不能显示指定目录的信息

以上代码在OpenSuse Leap42.1上测试通过,参考原书《Unix/Linux编程实践教程》,但是含有个人修改部分,不影响功能。

转载于:https://www.cnblogs.com/NJdonghao/p/5257721.html

Understanding Unix/Linux Programming-ls指令练习二相关推荐

  1. unix/linux命令“ls -l”选项输出结果详解

    from: http://hi.baidu.com/hoxily/item/12e2a02d03f77e0942634a8e unix/linux命令"ls -l"选项输出结果详解 ...

  2. 【Linux】Linux下基本指令(二)

    作者:一个喜欢猫咪的的程序员 专栏:<Linux> 喜欢的话:世间因为少年的挺身而出,而更加瑰丽.                                  --<人民日报& ...

  3. Linux下基本指令(二)

    man指令(重要): Linux的命令有很多参数,我们不可能全记住,我们可以通过查看联机手册获取帮助. 访问Linux⼿册页的命令是man 常⽤: 命令 功能 -k 根据关键字搜索联机帮助 num 只 ...

  4. Understanding Unix/Linux Programming-终端控制和信号

    软件工具:从文件或者stdin读取数据写到stdout 对磁盘文件和设备文件不加区分的程序称为软件工具.软件工具从标准输入读取字节,进行一些处理,然后将包含结果的字节流写到标准输出.工具发送错误消息到 ...

  5. 学习Unix/Linux编程要学些什么

    最近利用空余时间看了一下<Unix/Linux编程实践教程>,原书名为:Understanding Unix/Linux Programming: A Guide to Theory an ...

  6. 【Linux】——基本指令

    目录 前言 添加与删除用户 添加一个普通用户账号 删除账号 Linux快捷键 ls指令 pwd指令 whoami指令 cd指令 clear指令 touch指令 mkdir指令 rmdir指令 rm指令 ...

  7. Mac终端指令总结「Unix/Linux区别和联系、终端指令原理、Mac目录结构」

    一.认识UNIX和Linux 1.了解Unix和Linux的关系 下图Unix族谱 3.UNIX/Linux系统结构 UNIX/Linux 系统可以粗糙地抽象为 3 个层次(所谓粗糙,就是不够细致.精 ...

  8. linux unix shell programming,UnixampLinux Shell Programming I.ppt

    <Unix&ampLinux Shell Programming I.ppt>由会员分享,可在线阅读,更多相关<Unix&ampLinux Shell Program ...

  9. Mastering Embedded Linux Programming 学习 (二)在百问网157开发板上,编译构建u-boot

    Mastering Embedded Linux Programming 学习 (二)在百问网157开发板上,编译构建u-boot 一.下载u-boot源码 git clone https://git ...

  10. 【Linux】基础指令(二)

    目录 一.more 二.less 三.head 四.tail 五.管道 六.date 七.cal 八.which 九.alias 十.grep 十一.xargs 十二.find 十三.zip 十四.t ...

最新文章

  1. 【Flutter】Flutter 布局组件 ( Wrap 组件 | Expanded 组件 )
  2. Eclipse高版本无法兼容FatJar的问题解决
  3. 用分类行为解释为什么破碎的鸡蛋不能还原为一个完整的鸡蛋
  4. php access control allow origin,js请求跨域问题--Access-Control-Allow-Origin
  5. nod找不到服务器,node.js – 带有nodejs child_process的ssh,在服务器上找不到命令
  6. ELK5.3环境部署
  7. ubuntu16.04登录mysql出现1045的报错或者2002报错
  8. 2020年python2停止更新_Python核心团队计划2020年停止支持Python2,NumPy宣布停止支持计划表...
  9. Proxy error: Could not proxy request /api/ from localhost:8080 to http://localhost:80
  10. android tab pageview,Android Fragment在ViewPager中到底经历了什么?
  11. shell_exec() php 执行shell脚本
  12. css文字不被点击,css 让文字不被选中之-moz-user-select 属性介绍
  13. 计算机的五大组成部分(计组学习一)
  14. 前馈神经网络_深度学习基础理解:以前馈神经网络为例
  15. 《0bug-C/C++商用工程之道》首版勘误表
  16. 我的Android之路
  17. 经验总结:完整做完一款游戏需要经历哪些流程?
  18. 根据身份证号计算年龄 15位或18位身份证号的年龄计算方法
  19. WSL:关闭WSL【vmmem 进程占用CPU资源的解决办法】
  20. 计算机开机按f1,电脑开机要按f1怎么解决 开机按F1的各种解决方法整理

热门文章

  1. 催眠与大脑的信息处理
  2. cve2018 linux内核提权漏洞,CVE-2018-18955:较新Linux内核的提权神洞分析
  3. mysql的初始化语句是_MySQL入门之预处理语句的使用
  4. 护卫神 mysql 升级_护卫神php套件 php版本升级方法
  5. java 性能框架_Java Fork Join 框架(四)性能
  6. C++中 模板Template的使用
  7. 如何让Java文件在虚拟机中运行_深入理解JVM--Java程序如何在虚拟机中运行
  8. java setmodal 不管用_java – 无法动态设置setVisibility()参数
  9. php怎么输出指定数据类型,PHP变量的输出和数据类型
  10. 图书管理系统c++_图书管理功能