当前位置:网站首页>编写自己的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
边栏推荐
- Scratch big fish eat small fish Electronic Society graphical programming scratch grade examination level 2 true questions and answers analysis June 2022
- ES6 const essence and completely immutable implementation (object.free)
- 历史上的今天:九十年代末的半导体大战;冯·诺依曼发表第一份草案;CBS 收购 CNET...
- 7-Zip 遭抵制?呼吁者定下“三宗罪”:伪开源、不安全、作者来自俄罗斯!
- BSN长话短说之十:如何保证NFT的安全
- Installation and use of NoSQL database
- Niuke monthly race 22 tree sub chain
- HMS Core音频编辑服务3D音频技术,助力打造沉浸式听觉盛宴
- 全球基金和资管的股票建仓率达到15年内新低
- 嵌入式开发用到的一些工具
猜你喜欢

那个程序员,被打了。

Packetdrill script analysis guide

Spark's action operator

How to realize the usage of connecting multiple databases in idel

SQL learning notes (01) - basic knowledge of database

华为帐号多端协同,打造美好互联生活

Computer USB, HDMI, DP various interfaces and speeds

奇怪,为什么ArrayList初始化容量大小为10?

Construction of esp8266 FreeRTOS development environment

CSDN一站式云服务开放内测,诚邀新老用户来抢鲜
随机推荐
js变量提升(hoisting)
全球基金和资管的股票建仓率达到15年内新低
Flinkv1.13 implementation of financial anti fraud cases
SQL learning notes (04) - data update and query operations
项目采购管理
Network partition notes
Wechat applet WebView prohibits page scrolling without affecting the implementation of overflow scrolling in the business
Postgraduate entrance examination vocabulary 2023 sharing (1)
Click the screen with your finger to simulate F11 and enter the full screen
Swag init error: cannot find type definition: response Response
Computer USB, HDMI, DP various interfaces and speeds
ES6 decoupling top-level objects from windows
集成积木报表报错 org.apache.catalina.core.StandardContext.filterStart 启动过滤器异常
Packetdrill script analysis guide
JS scope chain and closure
scratch大鱼吃小鱼 电子学会图形化编程scratch等级考试二级真题和答案解析2022年6月
京东与腾讯续签三年战略合作协议;起薪涨至26万元!韩国三星SK争相加薪留住半导体人才;Firefox 102 发布|极客头条...
Scratch big fish eat small fish Electronic Society graphical programming scratch grade examination level 2 true questions and answers analysis June 2022
Niuke monthly race 22 tree sub chain
CSDN's one-stop cloud service is open for internal testing, and new and old users are sincerely invited to grab the fresh