Linux下who命令之C语言实现
Linux下who命令之C语言实现
Step1:前期准备
首先要有一个清楚的认识:linux中一切皆文件
实现who命令,who命令也是Linux中的一个文件,那我们怎么找到它呢?我们可以“找男人”(man),终端下执行命令:
man who此处我装了汉译版的man手册,查看到这样一段提示如下:

所以退出man手册,执行命令:
info who找到如下图相关信息:

也可以找到下面这样的一段话,也就是说:who命令可以这样实现,读取utmp里边的内容,然后显示记录,最后关闭utmp,who命令就是一个很简单的体现吧,打开文件,保存文件id,根据文件id读取用户的登陆信息,显示在终端。

我们尝试地打开一下
/var/run/utmp这个文件得到如下画面,发现是一串乱码,但还是能看出相关who的信息的
既然不清楚
utmp是干嘛的,我们可以使用man -k来检索一下相关信息,得到信息如下
经过筛选,发现只有
utmpx(5)是符合我们要求的,其中后面显示的是login records,而who命令不就是用来输出登录信息的;man的第五个类型表示的是文件格式和规范,说明此处可能存储了登录记录的数据结构使用指令:
man 5 utmpx,可以得到如下有用信息:
也可以使用输出重定向指令
man 5 utmpx > utmp.txt,得到文本格式的utmp数据结构体如下:
struct utmp {
short ut_type; /* Type of record */
pid_t ut_pid; /* PID of login process */
char ut_line[UT_LINESIZE]; /* Device name of tty - "/dev/" */
char ut_id[4]; /* Terminal name suffix,
or inittab(5) ID */
char ut_user[UT_NAMESIZE]; /* Username */
char ut_host[UT_HOSTSIZE]; /* Hostname for remote login, or
kernel version for run-level
messages */
struct exit_status ut_exit; /* Exit status of a process
marked as DEAD_PROCESS; not
used by Linux init (1 */
/* The ut_session and ut_tv fields must be the same size when
compiled 32- and 64-bit. This allows data files and shared
memory to be shared between 32- and 64-bit applications. */
#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
int32_t ut_session; /* Session ID (getsid(2)),
used for windowing */
struct {
int32_t tv_sec; /* Seconds */
int32_t tv_usec; /* Microseconds */
} ut_tv; /* Time entry was made */
#else
long ut_session; /* Session ID */
struct timeval ut_tv; /* Time entry was made */
#endif
int32_t ut_addr_v6[4]; /* Internet address of remote
host; IPv4 address uses
just ut_addr_v6[0] */
char __unused[20]; /* Reserved for future use */
};
此时万里长征已走一半,对比系统who命令,发现该结构体中并没有直接给出用户登录时间的成员变量,而是内嵌了一个
ut_tv的时间结构体,其中成员变量tv_sec才是我们需要的。如果耐心地看完该帮助文档,可以在下面一段代码中有新的发现:

此处定义了一个ut_time的宏,指向的就是
ut_tv.ut_sec,而我们需要用到的不是这样一个以秒为单位的格林威治标准时间,所以才后面需用到ctime()函数。在这儿用的就是刚刚说的linux的一个思想,一切事物都是文件。
Step2:其余头文件的准备
time.h:将格林威治标准时间(GMT)长整形的数时间转化为我们所熟悉的时间表示,运用ctime()函数string.h:调整输出格式,后面调试时会提到用处。- 其余头文件:因为要打开文件嘛,所以有些头文件必不可少,这个在我本周博客中有详细介绍:博客地址
Step3:编程思想
查看UTMP_FILE宏:
grep -nr UTMP_FILE /usr/include
读取其结构体,将需要的变量提取出来并按照一定的格式输出
其中,时间输出本来是一串格林威治标准时间(GMT)长整形的数,可以用ctime()将把日期和时间转换为字符串
Step4:代码实现
- who代码
- 其中等下需要修改的代码贴在此处:
void showtime(long timeval)
{
char* cp;
cp = ctime(&timeval);
printf("%s",cp+4); //+4是因为*cp所指的一串字符前4个字符表示为“星期”,可以忽略此信息
}
Step5:编译执行
执行结果如下:

发现“(:0)”被换行了,但是程序中并没有输出换行字符。经过一番思索后,猜想ctime()函数的返回值
*cp可能自动在最后补了一个字符\n。
Step6:调试代码
- 那只要能回退一个字符就好了,比如输出一个
\b(退格字符) - 编译再运行,发现输出格式仍是原样,最后经过了解
\b确实是可以回退一个字符,但是并不能实现退到上行,也就是不能消除\n带来的影响 - 百度之后,说可以通过输出
\r\b来实现“退行”,但实践后发现也不可取 - 最后考虑到直接修改
*cp字符串中最后一个字符为\0,使输出达到与系统who命令一样的效果 - 在输出语句前添加如下代码(需用到
string.h):cp[strlen(cp)-1] = '\0'
- 最后编译执行效果,可以看出与who命令基本一致:

Linux下who命令之C语言实现的更多相关文章
- 20155212 C语言实现linux下pwd命令的两种方法
20155212 C语言实现linux下pwd命令的两种方法 学习pwd命令 通过man pwd命令查看 pwd [OPTION],一般不加参数 -P显示当前目录的物理路径 -L显示当前目录的连接路径 ...
- Linux下ls命令显示符号链接权限为777的探索
Linux下ls命令显示符号链接权限为777的探索 --深入ls.链接.文件系统与权限 一.摘要 ls是Linux和Unix下最常使用的命令之一,主要用来列举目录下的文件信息,-l参数允许查看当前目录 ...
- linux下的命令是如何运行的
linux下的命令分为内建命令.可执行文件.脚本文件 shell终端里键入一个命令,如ls.cd.bash,shell会先查询一个环境变量PATH,它存了各种可执行文件的路径,输入$PATH可以打印变 ...
- Linux下ps命令详解 Linux下ps命令的详细使用方法
http://www.jb51.net/LINUXjishu/56578.html Linux下的ps命令比较常用 Linux下ps命令详解Linux上进程有5种状态:1. 运行(正在运行或在运行队列 ...
- 例解 Linux 下 Make 命令
Linux 下 make 命令是系统管理员和程序员用的最频繁的命令之一.管理员用它通过命令行来编译和安装很多开源的工具,程序员用它来管理他们大型复杂的项目编译问题.本文我们将用一些实例来讨论 make ...
- linux下history命令显示历史指令记录的使用方法
Linux系统当你在shell(控制台)中输入并执行命令时,shell会自动把你的命令记录到历史列表中,一般保存在用户目录下的.bash_history文件中.默认保存1000条,你也可以更改这个值 ...
- linux下svn命令使用大全
最近经常使用svn进行代码管理,这些命令老是记不住,得经常上网查,终于找了一个linux下svn命令使用大全:1.将文件checkout到本地目录 svn checkout path(path是服务器 ...
- Linux下rz命令使用的实例详解
Linux中rz命令和sz命令都可用于文件传输,而rz命令主要用于文件的上传,下面将通过几个实例来给大家详细介绍下Linux下rz命令的用法,一起来学习下吧. rz命令可以批量上传文件,当然也可上传单 ...
- Linux下rar命令详解
Linux下rar命令详解 用法: rar <命令> -<选项1> ….-<选项N> < 操作文档> <文件…> <@文件列表…> ...
随机推荐
- Sql Server之旅——第十一站 简单说说sqlserver的执行计划
我们知道sql在底层的执行给我们上层人员开了一个窗口,那就是执行计划,有了执行计划之后,我们就清楚了那些烂sql是怎么执行的,这样 就可以方便的找到sql的缺陷和优化点. 一:执行计划生成过程 说到执 ...
- OOP应用:实体类
实体类 定义:实体类是一个业务实体的类,而业务实体就是整个软件系统业务所涉及的对象. 使用: 1.新增实体类项目,增加类库项目,以.Modes作为后缀. 2.抽取对象以及属性.(简单地说,对象就是每个 ...
- 用struts2获取session、request、parmeter的方法
package com.hanqi.action; import java.util.Map; import com.opensymphony.xwork2.ActionContext; public ...
- JNA 如何 加载多个 存在依赖的 DLL 库
JNA 的出现,极大的简化了原有的 JNI 技术.下面是JNA github地址:https://github.com/java-native-access/jna 1. 简单的一个例子: /** S ...
- CentOS 7最小化安装后找不到‘ifconfig’命令——修复小提示
如果你不知道在哪里可以找到ifconfig命令,请按照以下简单的步骤来找到它.首先,让我们找出哪个包提供了ifconfig命令.要完成这项任务,输入以下命令: [root@jrserver app_f ...
- Linux磁盘管理之元数据、文件和目录、链接文件03
一.存储设备分区简述 文件系统最终目的是把大量数据有组织的放入持久性的存储设备,如硬盘.硬盘存储能力具有持久性,不会因为断电而消失,存储量大,但读取速度慢.操作系统读取硬盘的时候,不会一个一个扇区读取 ...
- view类的setVisibility
android view setVisibility():有三个参数:Parameters:visibility One of VISIBLE, INVISIBLE, or GONE,想对应的三个常量 ...
- 图灵机器人(问答机器人)API调用示例
问答机器人API文档:https://www.juhe.cn/docs/api/id/112 先上图: 说下大致实现的步骤: 1.首先使用了聚合数据的sdk,这样免费使用的数目可以多一些 2.使用gs ...
- 《硝烟中的Scrum和XP》:作者主导Scrum过程的实战经验,四星推荐
本书作者是开发团队Leader,本书记录了他带领团队实施Scurm过程中的经验教训.全书短小精悍,言简意赅. 以下是书中一些观点信息的摘抄: 1:Nokia总结出的迭代开发的基本要求:1.1:迭代要有 ...
- 【转载】阎焱:90后创业是扯淡 大量O2O和P2P公司濒临倒闭
真正创业成功的大部分是年龄在30岁到38岁之间,很多90后基本什么都不懂.从历史来看,在这样的人口大国,集体性行为,无论是政治的还是经济的,基本都是导致灾难性后果. 10月14日消息,赛富基金创始首席 ...