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

    xiaoxiao2026-08-23  3

    注:以下内容仅仅是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) 进入该文件读取信息

     打开该文件(open) 读取信息(read)关闭文件描述符(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; }  

    
    转载请注明原文地址: https://ju.6miu.com/read-1311469.html
    最新回复(0)