Unix/Linux编程实践(who)
平台:FreeBSD 12.1-RELEASE
本章主要学习:
1)who命令能做些什么?
2)who命令如何工作?
3)如何编写who?
who命令主要用于查看当前谁在使用系统,直接在shell中输入相关命令并回车:
%who
%who am i
%who am I
%whoami
要了解who如何工作,先查看who命令手册:
%man who
里面详细列出who使用方法,那么如何去实现这个命令呢?首先要找出.h头文件。上面命令输出显示的内容中有如下内容:
显示跟utx文件有关,于是可以再搜索与utx有关的内容:
%man -k utx
如果想知道man命令中这个k选项的意思,同样可以用man man命令查看,显示结果如下:
这个选项意思是模仿apropos查找命令,所以命令man -k utx显示结果如下(用apropos utx也是一样的结果):
似乎跟getutexent有关,于是可以用man getutxent命令查看其说明:
这里显示跟utmpx.h头文件有关,所以我们可以用vi /usr/include/utmpx.h命令查看这个头文件的内容了。
两种方法实现who命令:
who1.c
1 /* 2 * who1.c -- a first version of the who program 3 * Target: open, read UTMP file, and show results. 4 * 5 * System: FreeBSD 12.1-RELEASE 6 * Compiler: clang 8.0.1 7 * 8 * Compiler command: clang -Wall -O3 -o who1 who1.c 9 */ 10 11 #include <stdio.h> 12 #include <utmpx.h> 13 #include <fcntl.h> 14 #include <unistd.h> 15 #include <stdlib.h> 16 17 #define SHOWHOST 1 18 19 void show_info(struct utmpx *); 20 21 int main(void) 22 { 23 struct utmpx *current_record; 24 setutxent(); 25 26 while ((current_record = getutxent()) != NULL) { 27 if (current_record->ut_type != USER_PROCESS) { /* Only display user process */ 28 continue; 29 } 30 show_info(current_record); 31 } 32 endutxent(); 33 return 0; 34 } 35 36 /* 37 * show_info() 38 * displays contents of the utmpx struct in human readable form 39 * <note> these sizes should not be hardwired 40 */ 41 void show_info(struct utmpx *utbufp) 42 { 43 printf("%-8.8s ", utbufp->ut_user); /* User login name. */ 44 printf("%-8.8s ", utbufp->ut_line); /* Device name. */ 45 printf("%-8d ", utbufp->ut_tv.tv_sec); /* Time entry was make. */ 46 47 #if SHOWHOST 48 printf("%-8.8s ", utbufp->ut_host); /* Remote hostname. */ 49 #endif 50 putchar(\'\n\'); 51 }
第二种方法实现who命令,主要是在时间显示这一块进行改进:
who2.c
1 /* 2 * who2.c -- a first version of the who program 3 * Target: open, read UTMP file, and show results. 4 * 5 * System: FreeBSD 12.1-RELEASE 6 * Compiler: clang 8.0.1 7 * 8 * Compile command: clang -Wall -O3 -o who2 who2.c 9 */ 10 11 #include <stdio.h> 12 #include <utmpx.h> 13 #include <fcntl.h> 14 #include <unistd.h> 15 #include <stdlib.h> 16 #include <time.h> 17 18 #define SHOWHOST 1 19 20 void show_info(struct utmpx *); 21 void show_time(long); 22 23 int main(void) 24 { 25 struct utmpx *current_record; 26 setutxent(); 27 28 while ((current_record = getutxent()) != NULL) { 29 if (current_record->ut_type != USER_PROCESS) { /* Only display user process */ 30 continue; 31 } 32 show_info(current_record); 33 } 34 endutxent(); 35 return 0; 36 } 37 38 /* 39 * show_info() 40 * displays contents of the utmpx struct in human readable form 41 * <note> these sizes should not be hardwired 42 */ 43 void show_info(struct utmpx *utbufp) 44 { 45 printf("%-8.8s\t", utbufp->ut_user); /* User login name. */ 46 printf("%-8.8s\t", utbufp->ut_line); /* Device name. */ 47 /*printf("%-8d\t", utbufp->ut_tv.tv_sec);*/ /* Time entry was make. */ 48 show_time(utbufp->ut_tv.tv_sec); 49 #if SHOWHOST 50 printf("%-8.8s\t", utbufp->ut_host); /* Remote hostname. */ 51 #endif 52 putchar(\'\n\'); 53 } 54 55 /* 56 * Display time in a format fit for human consumption 57 * Uses ctime to build a string then picks parts out of it 58 * Note: %12.12s prints a string 12 chars wide and LIMITS 59 * it to 12 chars. 60 */ 61 void show_time(long timeval) 62 { 63 char *cp; /* to hold address of time. */ 64 cp = ctime((const time_t *)(&timeval)); 65 printf("%12.12s\t", cp+4); 66 }
编译运行,并跟系统内置的who命令进行比较,基本达到我们的需求:
总结:
本文主要学习who命令的作用,另外,也掌握了我们如何用内置文档去获取我们想要了解的内容,如何根据蛛丝马迹搜索文档,搜索学习能力很重要。另外,如何查看头文件,我们在自己编写程序的过程中需要反复地查看头文件中的函数和变量声明,搞懂它们的作用。