查看联机帮助与who命令的实现

查看联机帮助与who命令的实现

一、背景

通过对who命令的系统编程来学会查看联机帮助,学习使用联机帮助来查找到有用的信息。并且学习linux的文件操作。

二、实现过程

1、了解who命令的作用

    

我这里登陆了三个用户root,pf,pf2。可以看到who命令的作用:第一列是用户名的名称,第二列是终端的名称,第三列是登陆的时间(这里没有用时间戳的形式),第四列是用户登录的IP地址。了解了这些之后,就明白了自己的目的。有了目的接下来就是怎么实现了。自己首先猜测,who命令的实现有可能是从哪个配置文件中调出来的系统的信息,至于具体是怎样就不甚明白了。于是就想到了查找用户手册。

2、通过手册来检索有用的信息

man命令来查看whoSynopsiswho的基本用法。这个不是想要的。可以在description中找到这样一句话。

 

这句话是说如果文件没指定参数。那么就从/var/run/utmp/var/log/wtmp中来读取信息。那么到底这两个文件是干什么的呢?我们知道/var目录下是存可扩充不断更改的变量信息的。这就不明白了。于是需要进一步往下看。

see also中我找到了一句有用的话。是说如果电脑支持的话可以用info who来查看更完整的手册。

这里又找到了类似于man手册中的一句话。是说如果只使用who命令而无参数的话,那么会从/var/run/utmp中读取正在登录的用户信息。意思与man中的意思大概相同。现在就需要来看看utmp是个什么东西了。

首先我想先用more来查看一下,但是发现什么都没有。那就另辟蹊径。用man -k命令来根据关键字搜索联机帮助。

从这里可以找一下。发现倒数第四行和最后一行最像是我想要的东西。共同点是都是第5小节的东西。而第5小节都是配置文件的帮助。这个就无所谓了,总之用man 5 utmp来查看一下吧。

这里首先看到了utmp的头文件。

并且从这里看以看出,utmp是一个结构体类型啊,而且这里面包含了我想要的东西。再进/usr/include/utmp.h看看,找到读取的文件的宏定义名。

3.linux的文件操作

     到了这里,头脑逐渐清晰起来了。我需要从utmp文件中将类型为utmp的结构体都出来,并且,选择出我需要的信息来进行输出就可以了。现在的问题在于如何打开文件,如果读取文件以及如何关闭文件。因为这里需要读的结构体中的信息。当然这里又需要用到man命令了。先用man -k read来查看,就会发现屏幕列出了一大堆,一个一个找也行,但费时费力的,而且事倍功半。所以使用grep file命令来过滤一下就好了。这样就可以找到关于文件的读命令了。

这里找到了两个关于read的命令,看看第一个好了,后面的英语是讲:从文件描述符中读取。

首先看到了这里的头文件,因为是系统调用,这里必须要有头文件的。然后看到这个read命令的用法是如何的。这里的问题又出来了,如何得到文件描述符呢?文件描述符显然并不是文件名或文件的指针。那就继续往下看看吧。

看到这里,眼睛当然注意到了openclose命令,这一看就很有可能是自己需要的文件打开与关闭命令。再进行open命令与close命令的手册查看就能找到他们的头文件和使用方法了。我这里就不再详细说了,要不然就显得太啰嗦了。查看方法和read基本类似。

4.实现过程

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#include<unistd.h>

#include<utmp.h>

#include<fcntl.h>

 

#define SHOWHOST

 

void showtime(long time);

void show_record(struct utmp *a);

int main()

{

        int fd;

        struct utmp record;

        if((fd=open(UTMP_FILE,O_RDONLY))==-1)

        {

        perror(UTMP_FILE);

        exit(1);

        }

        while(read(fd,&record,sizeof(record))==sizeof(record))

        show_record(&record);

        close(fd);

        return 0;

}

 

void show_record(struct utmp *a)

{

        if((a->ut_type)!=USER_PROCESS)

        return ;

        printf("%-8.8s",a->ut_name);

        printf(" ");

        printf("%-8.8s",a->ut_line);

        printf(" ");

        showtime(a->ut_time);

#ifdef SHOWHOST

        if(a->ut_host[0]!='\0')

        printf("(%s)",a->ut_host);

#endif

        printf("\n");

}

 

void showtime(long time)

{

        printf("%12.12s",ctime(&time)+4);

}

                        

 

这里需要特别注意几个问题:

(1)格式要注意,在字符串输出的时候不注意格式输出的东西将会和who十分不相像。

(2)这里用到了时间的转换命令ctime,如果不使用该命令的话可见时间是时间戳的形式,即使一大长串的数字,其实这个数字表示的是从1970110时开始计算的秒数。

(3)要对输出的用户登录名进行过滤,只显示输出普通用户的登陆名及其信息。

5.实现结果

三、总结

    从who命令的实现,我学习到了man的使用技巧。包括如何使用man -k来查找相关信息,并且使用grep来进行过滤无用的信息。同时,学习了如何输出文件中的结构体的内容,这不同于more命令实现中的gets命令。不过在学习的过程中还是发现了不少问题,有一些概念不清晰导致编程的时候虽然编程结果没错,但过程的思路并不清晰,这需要多看书,理清楚一些基础的东西。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值