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> < 操作文档> <文件…> <@文件列表…> ...
随机推荐
- 6、后记:PMO项目管理 - PMO项目管理办公室
PMO项目管理办公室的作用,按笔者所简化的理解,其作用就是将项目资源标准化.规范化.文档化.然后,根据实际的项目情况,对项目间的资源内容进行协调沟通和培训,让项目组能够更快更好的完成项目建设任务. 不 ...
- HashMap常用方法
当需要对元素进行计数时,HashMap非常有用,如下例子,统计一个字符串中每个字符出现的次数: package simplejava; import java.util.HashMap; import ...
- ASP.NET MVC 在控制器中获取某个视图动态的HTML代码
如果我们需要动态的用AJAX从服务器端获取HTML代码,拼接字符串是一种不好的方式,所以我们将HTML代码写在cshtml文件中,然后通过代码传入model,动态获取cshtml中的HTML代码 当然 ...
- SQL SERVER 查看数据库表的字段类型,是否允许为NULL,默认值,主键等
)-- 表名 set @table_name='bqcform101' --============表结构 select 类别,表名or字段名,描述,字段类型,是否自增,允许为NULL,默认值 fro ...
- 使用数据库sqlite3 C语言实现登陆注册的功能
//此代码为注册功能 void create_regtable() { int rc; //rc为返回值,判断函数是否执行成功 rc=0函数执行成功,rc !=0函数执行失败 sqlite3 *db; ...
- TCP的关闭,到底是几次握手,每次的标志位到底是什么!
做题的时候遇到一个问题,TCP关闭的时候到底是三次还是四次握手,如果是三次,少了哪部分? 按照 <计算机网络> -第五版-谢希仁 然而对于TCP关闭, 有的地方能找到 ...
- 如何更改nginx网站根目录 以及解析php
nginx默认网站根目录为/usr/local/nginx/html,如果想要将它改成/data/www 需配置 vim /usr/local/nginx/conf/nginx.conf 将其中的字段 ...
- webkit浏览器常见开发问题
前段时间有人问我一个简单的问题,html如何创建解析的? 我讲了一大堆,什么通过DocumentLoader, CachedResourceLoader, CacheResource, Resourc ...
- 一次Mutex死锁的原因探究
1.现象 最近项目中调出一个bug,某些时候程序会卡死不动,用windbg进行加载后用 ~*kb 命令列出所有的线程栈调用,发现有多个线程调用 WaitForMultipleObjects 在等 ...
- hdu5269 Chip Factory
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5536 题目: Chip Factory Time Limit: 18000/9000 MS ( ...