当前位置:网站首页>编写自己的who命令
编写自己的who命令
2022-07-01 09:39:00 【全栈程序员站长】
大家好,又见面了,我是你们的朋友全栈君。
今天自己照着书一步步敲了who命令的实现。老外写的有些书就是不错,一步步启发你告诉你怎么思考,怎么根据已有的线索查询联机帮助,怎么一步步最终解决问题。真不错。 下面我就根据书上的思想,来回顾一下这将近2个小时的工作。
1.who命令能做什么2.who命令是怎么工作的3.怎样编写who命令
1.who命令能做什么
我们可以在命令行下输入who命令,结果如下:[email protected]:~ whocaoli tty2 2010-11-23 15:41caoli tty7 2010-11-23 15:30 (:0)caoli pts/0 2010-11-23 16:12 (:0.0)caoli pts/1 2010-11-23 16:51 (:0.0)[email protected]:~
通过联机帮助 man who
: Print information about users who are currently logged in.
who可以显示出当前系统中已经登录的用户的信息。 可以大概知道who的作用以及对它的描述和使用的一些选项等。。。。
2.who命令是怎么工作的 step1: 根据man who中: If FILE is not specified, use /var/run/utmp.
可以知道who是从/var/run/utmp中获得用户登录信息的。
step2: 现在我们知道的是一个目录,下一步就是要找到跟他相关的信息。 man -k 选项可以根据关键字查找。 所以man -k utmp 就能找到utmp(4) 的相关信息,:::我是直接man utmp的。
step3: 再来查看utmp里的详细信息: more /usr/include/utmp.h 这时候,我们会发现utmp里面保存的是结构数组。记录的用户登录的相关信息。
step4: 根据以上步骤可以推测who的工作原理: 把记录有用户登录信息的文件里的内容一条条读出。我们接着就可以根据这个思想来实现了。
3.怎样编写who命令 关键点:如何从文件里读取数据结构 这里就要用到一些文件操作相关的知识了 (这里要说的是系统调用和大一时学到的fopen等等不是一回事,其实个人觉得功能差不多)
接着我们就开始编码把 主函数部分: #include <utmp.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h>
#define SHOWHOST void show_info(struct utmp *utbufp);
int main(int argc, char** argv) { struct utmp current_record;//一个缓冲区 int utmpfd; //文件描述符 int reclen=sizeof(current_record); if((utmpfd=open(UTMP_FILE,O_RDONLY))==-1) { perror(UTMP_FILE); return 1; } while(read(utmpfd,¤t_record,reclen)==reclen) show_info(¤t_record); //显示utmp的内容 close(utmpfd); return 0; }
显示登录信息部分: void show_info(struct utmp *utbufp) { if(utbufp->ut_type!=USER_PROCESS) // 清除空白记录 return; printf(“%-8.8s/t”,utbufp->ut_name); printf(“%-8.8s/t”,utbufp->ut_line); // printf(“%10ld/t”,utbufp->ut_time); show_time(utbufp->ut_time); #ifdef SHOWHOST if(utbufp->ut_host[0]!=’/0′) printf(“(%s)”,utbufp->ut_host); #endif printf(“/n”); } 运行结果: [email protected]:~/workspace/test$ ./who1 reboot ~ 1290497376 (2.6.32-26-generic) runlevel ~ 1290497376 (2.6.32-26-generic) LOGIN tty4 1290497376 () LOGIN tty5 1290497376 () caoli tty2 1290498098 () LOGIN tty3 1290497376 () LOGIN tty6 1290497376 () LOGIN tty1 1290497384 () caoli tty7 1290497409 (:0) caoli pts/0 1290499920 (:0.0) caoli pts/1 1290501832 (:0.0) caoli pts/2 1290501833 () caoli pts/1 1290502298 (:0.0) caoli pts/2 1290506795 (:0.0) 这里的结果跟上面一开始who命令的结果做个比较,我们会发现 一,我们要过滤掉不是用户的名字二,要正确的显示时间三,不需要显示主机名的可以省略
根据第1点:做出改动如下 utmp结构体中有一项是ut_type,当他的值为7时,表示是一个已经登录的用户,所以可以对显示函数show_info中的显示用户稍作修改 void show_info(struct utmp *utbufp)utmp { if(utbufp->ut_type!=USER_PROCESS) // 清除空白记录 return; printf(“%-8.8s/t”,utbufp->ut_name);
根据第2点:我们根据time.h中的内容做改动,关于时间函数方面的内容,我已经在Linux程序设计第4章中学习过了,所以这里我就直接跳过去了。 ctime(##)中需要一个指向time_t的指针。返回的时间字符串类似下面 Wed Jun 30 21:49:09 1993/n 我们要从4位开始输出12个字符 printf(“%12.12s”,ctime(&t)+4); 所以添加show_time函数如下 void show_time(long timeval) { char *cp; cp=ctime(&timeval); printf(“%12.12s”,cp+4); } 注意ctime是在time.h里面的。所以程序开头部分要添加头文件。
第3点 这里有个预处理的定义,我不太懂,哥要是看到了,就评论一下呗! if(utbufp->ut_host[0]!=’/0′) printf(“(%s)”,utbufp->ut_host);
最后的代码如下:
#include <utmp.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <time.h>#define SHOWHOST void show_info(struct utmp *utbufp);void show_time(long);int main(int argc, char** argv){struct utmp current_record;//一个缓冲区int utmpfd; //文件描述符int reclen=sizeof(current_record);if((utmpfd=open(UTMP_FILE,O_RDONLY))==-1){perror(UTMP_FILE);return 1;}while(read(utmpfd,¤t_record,reclen)==reclen) show_info(¤t_record); //显示utmp的内容close(utmpfd);return 0;}void show_info(struct utmp *utbufp){ if(utbufp->ut_type!=USER_PROCESS) // 清除空白记录 return; printf(“%-8.8s/t”,utbufp->ut_name);printf(“%-8.8s/t”,utbufp->ut_line);show_time(utbufp->ut_time);#ifdef SHOWHOST if(utbufp->ut_host[0]!=’/0′) printf(“(%s)”,utbufp->ut_host);#endifprintf(“/n”);}void show_time(long timeval){char *cp;cp=ctime(&timeval);printf(“%12.12s”,cp+4);}
结果如下: [email protected]:~/workspace/test$ ./who1 caoli tty2 Nov 23 15:41 caoli tty7 Nov 23 15:30(:0) caoli pts/0 Nov 23 16:12(:0.0) caoli pts/1 Nov 23 16:51(:0.0) 到这里,已经跟原始的who命令相差无几了,哈哈。
通过这次实践,我最大的收获就是不能什么事都问别人,能自己找答案的就尽量自己找,这也是一种能力。 在这方面,我觉得老公做的很好,崇拜他一下! 好哥,向你致敬。 爱你的老婆。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/131751.html原文链接:https://javaforall.cn
边栏推荐
- Project procurement management
- JS use toString to distinguish between object and array
- The latest masterpiece of Alibaba, which took 182 days to produce 1015 pages of distributed full stack manual, is so delicious
- Error org apache. catalina. core. StandardContext. FilterStart start filter exception
- 那个程序员,被打了。
- js 使用toString 区分Object、Array
- Day06 branch structure and cycle (III)
- Unity tips for reducing the amount of code -- empty protection extension
- CSDN's one-stop cloud service is open for internal testing, and new and old users are sincerely invited to grab the fresh
- Closure implementation iterator effect
猜你喜欢
随机推荐
SDN_ Simple summary
Hololens2 development -6-eyetracking and speech recognition
Dspic30f6014a LCD block display
PHP merges multiple arrays. The same element takes the intersection of different elements to form an array
laravel postman 提交表单出现419错误。2020年7月6日记。
Some tools used in embedded development
Tree structure --- binary tree 1
Wechat applet WebView prohibits page scrolling without affecting the implementation of overflow scrolling in the business
硬件中台项目
短路运算符惰性求值
MT7628K eCos开发入门
年薪100万,在北上广深买的起房子吗?
js 使用toString 区分Object、Array
Click the screen with your finger to simulate F11 and enter the full screen
【无标题】
Differences between JS valueof and toString
SQL learning notes (04) - data update and query operations
吃一个女富豪的瓜。。。
js valueOf 与 toString 区别
Problems caused by delete and delete[]







