Understanding Unix/Linux Programming-ls指令练习二
- 完善ls练习一的功能:
- 排序,使用qsort
- 分栏,计算宽度和行数
- 文件“.”的显示需要由-a选项来选择
- 详细信息的显示,-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 的功能。但是有几点不足之处:
- 不显示总数,这个容易解决
- 未排序
- 不支持参数-a
- 假设参数只是目录名
- 不能显示指定目录的信息
以上代码在OpenSuse Leap42.1上测试通过,参考原书《Unix/Linux编程实践教程》,但是含有个人修改部分,不影响功能。
转载于:https://www.cnblogs.com/NJdonghao/p/5257721.html
Understanding Unix/Linux Programming-ls指令练习二相关推荐
- unix/linux命令“ls -l”选项输出结果详解
from: http://hi.baidu.com/hoxily/item/12e2a02d03f77e0942634a8e unix/linux命令"ls -l"选项输出结果详解 ...
- 【Linux】Linux下基本指令(二)
作者:一个喜欢猫咪的的程序员 专栏:<Linux> 喜欢的话:世间因为少年的挺身而出,而更加瑰丽. --<人民日报& ...
- Linux下基本指令(二)
man指令(重要): Linux的命令有很多参数,我们不可能全记住,我们可以通过查看联机手册获取帮助. 访问Linux⼿册页的命令是man 常⽤: 命令 功能 -k 根据关键字搜索联机帮助 num 只 ...
- Understanding Unix/Linux Programming-终端控制和信号
软件工具:从文件或者stdin读取数据写到stdout 对磁盘文件和设备文件不加区分的程序称为软件工具.软件工具从标准输入读取字节,进行一些处理,然后将包含结果的字节流写到标准输出.工具发送错误消息到 ...
- 学习Unix/Linux编程要学些什么
最近利用空余时间看了一下<Unix/Linux编程实践教程>,原书名为:Understanding Unix/Linux Programming: A Guide to Theory an ...
- 【Linux】——基本指令
目录 前言 添加与删除用户 添加一个普通用户账号 删除账号 Linux快捷键 ls指令 pwd指令 whoami指令 cd指令 clear指令 touch指令 mkdir指令 rmdir指令 rm指令 ...
- Mac终端指令总结「Unix/Linux区别和联系、终端指令原理、Mac目录结构」
一.认识UNIX和Linux 1.了解Unix和Linux的关系 下图Unix族谱 3.UNIX/Linux系统结构 UNIX/Linux 系统可以粗糙地抽象为 3 个层次(所谓粗糙,就是不够细致.精 ...
- linux unix shell programming,UnixampLinux Shell Programming I.ppt
<Unix&Linux Shell Programming I.ppt>由会员分享,可在线阅读,更多相关<Unix&Linux Shell Program ...
- Mastering Embedded Linux Programming 学习 (二)在百问网157开发板上,编译构建u-boot
Mastering Embedded Linux Programming 学习 (二)在百问网157开发板上,编译构建u-boot 一.下载u-boot源码 git clone https://git ...
- 【Linux】基础指令(二)
目录 一.more 二.less 三.head 四.tail 五.管道 六.date 七.cal 八.which 九.alias 十.grep 十一.xargs 十二.find 十三.zip 十四.t ...
最新文章
- 【Flutter】Flutter 布局组件 ( Wrap 组件 | Expanded 组件 )
- Eclipse高版本无法兼容FatJar的问题解决
- 用分类行为解释为什么破碎的鸡蛋不能还原为一个完整的鸡蛋
- php access control allow origin,js请求跨域问题--Access-Control-Allow-Origin
- nod找不到服务器,node.js – 带有nodejs child_process的ssh,在服务器上找不到命令
- ELK5.3环境部署
- ubuntu16.04登录mysql出现1045的报错或者2002报错
- 2020年python2停止更新_Python核心团队计划2020年停止支持Python2,NumPy宣布停止支持计划表...
- Proxy error: Could not proxy request /api/ from localhost:8080 to http://localhost:80
- android tab pageview,Android Fragment在ViewPager中到底经历了什么?
- shell_exec() php 执行shell脚本
- css文字不被点击,css 让文字不被选中之-moz-user-select 属性介绍
- 计算机的五大组成部分(计组学习一)
- 前馈神经网络_深度学习基础理解:以前馈神经网络为例
- 《0bug-C/C++商用工程之道》首版勘误表
- 我的Android之路
- 经验总结:完整做完一款游戏需要经历哪些流程?
- 根据身份证号计算年龄 15位或18位身份证号的年龄计算方法
- WSL:关闭WSL【vmmem 进程占用CPU资源的解决办法】
- 计算机开机按f1,电脑开机要按f1怎么解决 开机按F1的各种解决方法整理
热门文章
- 催眠与大脑的信息处理
- cve2018 linux内核提权漏洞,CVE-2018-18955:较新Linux内核的提权神洞分析
- mysql的初始化语句是_MySQL入门之预处理语句的使用
- 护卫神 mysql 升级_护卫神php套件 php版本升级方法
- java 性能框架_Java Fork Join 框架(四)性能
- C++中 模板Template的使用
- 如何让Java文件在虚拟机中运行_深入理解JVM--Java程序如何在虚拟机中运行
- java setmodal 不管用_java – 无法动态设置setVisibility()参数
- php怎么输出指定数据类型,PHP变量的输出和数据类型
- 图书管理系统c++_图书管理功能