Linux who命令的相关知识及初步编写(1)

注:以下内容仅仅是who命令的初步编写,并未实现其余的命令行选项

1.Linux系统中who命令的用途:

     打印已经登录系统用户的相关信息,如:

     name   tty7  2016-08-16   15:34  (:0)

     name2  tty1  2016-8-16     15:35  (:0.0)

    上述所列打印的信息中第一列为已经登录用户的用户名,第二列为终端名,第三列、第四列为登录时间,第五列为登录地址,两行分别代表目前所登录的两个不同用户


2.who命令的工作原理

    用户的登录信息必然需要存储在某个文件中,当用who查看这些信息时,首先进入该文件读取相关的存储信息,再将该信息以一定的形式打印出来。


3.如何自己实现一个who命令

  (1)首先需要确定存储相关信息的文件是什么

  (2) 进入该文件读取信息

  1.  打开该文件(open)
  2.  读取信息(read)
  3. 关闭文件描述符(close)

 (3) 打印在标准输出设备


4.具体实现

   (1)如何确定存储信息的文件是哪个?

         借助man命令查阅手册,查阅与who相关的信息(man who),可以看到出现了两个相关的文件名:“/var/run/utmp”,"/var/log/wtmp"

         可以猜测应该与这个文件有关,再深入了解一下这两个文件的相关信息,根据关键字“utmp”查阅手册(man -k utmp:man + -k表示根据关键字查阅),可以看到出现的信

         息中有一项是“utmp(5)   login records”,猜测其与登录信息有关,进一步查阅utmp(man 5 utmp),可以看到一个结构体(struct utmp),该结构体的元素即登录信息

         再看手册,可以发现该结构体在文件“utmp.h”中声明,而在/var/run/utmp中以该结构体的形式存储相关信息,因此写程序时包含头文件“utmp.h”,即可件“/var/run/utmp”中

         读取信息。

  (2)如何读取相关信息?

        打开文件(open),读取(read),完成后关闭(close)

 (3)需要改进的地方有哪些?

       文件中所包含的信息不止已登录用户的登录信息,还包含其他信息,应该清除其余的空白记录(由结构体中的ut_type的值来进行筛选)

       结构体中的登录时间用的是秒来表示,需转换成可阅读的形式来显示(ctime进行转换)

5.代码

    注:在代码中对函数加入了出错检查,并写成了出错处理封装函数

(1)file.h

#include<stdio.h>
#include<errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<stdlib.h>

void perr_exit(const char *str);
int Open(const char *pathname, int flags);
ssize_t Read(int fd, void *buf, size_t count);
int Close(int fd);

(2)file.c(出错处理封装函数)

#include"file.h"

void perr_exit(const char *str)
{
 perror(str);
 exit(-1);
}

int Open(const char *pathname, int flags)
{
 int res;

 if((res=open(pathname,flags))<0)
 {
  perr_exit("open");
 }
 else
  return res;
 
}

ssize_t Read(int fd, void *buf, size_t count)
{
 ssize_t res;

 res=read(fd,buf,count);
 if(res<0)
 {
  perr_exit("read");
 }
 else
  return res;
}

int Close(int fd)
{
 if(close(fd)<0)
 {
  perr_exit("close");
 }
 else
  return 0;
}


(3)main.c(实现了登录信息的读取及打印)

#include"file.h"
#include<utmp.h>
#include<time.h>

void show_info(struct utmp buf)//用于实现时间形式的转换以及相关信息的打印
{
 char *time=NULL;
 time=ctime(&buf.ut_time);
 if(time==NULL)
 {
  perr_exit("ctime");
 }
 printf("%-8.8s",buf.ut_name);
 printf(" ");
 printf("%-8.8s",buf.ut_line);
 printf(" ");
 printf("%-12.12s",time+4);
 printf(" ");
//#ifdef SHOWHOST
 printf("(%s)",buf.ut_host);
//#endif
 printf("\n");
 return;
}

int main(void)
{
 int fd;
 struct utmp buf;

 fd=Open("/var/run/utmp",O_RDONLY);
 while(Read(fd,&buf,sizeof(struct utmp))==sizeof(buf))
 {
  if(buf.ut_type!=USER_PROCESS)
   continue;
  else
   show_info(buf);
 }
 Close(fd);
 return 0;
}  



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值