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命令的作用,另外,也掌握了我们如何用内置文档去获取我们想要了解的内容,如何根据蛛丝马迹搜索文档,搜索学习能力很重要。另外,如何查看头文件,我们在自己编写程序的过程中需要反复地查看头文件中的函数和变量声明,搞懂它们的作用。

 

posted @ 2020-02-22 22:09  Mocuishle007  阅读(445)  评论(0编辑  收藏  举报