zoukankan      html  css  js  c++  java
  • Linux---who命令学习

    who命令

    获取正在登录系统的用户

    使用Linux的who命令 

    第一个参数book代表用户名,第二个参数tty7代表终端名,第三个参数代表时间,第四个参数代表用户的登录地址。

    阅读手册

    使用命令读手册

    $ man who

    可以知道who这个命令从 /var/run/utmp 和 /var/log/wtmp 两个文件中获取数据,

    再通过命令,查找关于 “utmp” 的信息

    $ man -k utmp

    -k的意思是根据关键字查找

    $man 5 utmp

    我们查询到一些关于utmp结构体中的元素,比如ut_user用户名字、ut_line用户设备、ut_time登录时间等。

    who命令的工作流程

            打开utmp

       +---->  读取记录 ------   +

       |                   |

       +-------显示记录        |

          关闭utmp  <------ +

    who命令的编写---版本1

     1 #include <stdio.h>
     2 #include <utmp.h>
     3 #include <fcntl.h>
     4 #include <unistd.h>
     5 #include <time.h>
     6 
     7 void show_info(struct utmp *utbufp);
     8 int main()
     9 {
    10     struct utmp current_record;
    11     int utmp_fd;
    12     int reclen = sizeof(current_record);    
    13 
    14     utmp_fd = open(UTMP_FILE,O_RDONLY);    
    15     if(utmp_fd == -1)
    16     return -1;
    17 
    18     while( read(utmp_fd, &current_record,reclen) == reclen )
    19      show_info(&current_record);
    20     
    21     close(utmp_fd);
    22     return 0;
    23 }
    24 
    25 void show_info(struct utmp *utbufp)
    26 {
    27 
    28     printf("%-8.8s",utbufp->ut_name);
    29     printf(" ");
    30     printf("%-8.8s",utbufp->ut_line);
    31     printf(" ");
    32     printf("%101d",utbufp->ut_time);
    33     printf(" ");
    34     printf("(%s)",utbufp->ut_host);
    35     printf(" ");
    36     printf("
    ");
    37 }

    输出结果:

     

    问题:

    1. 有部分数据不是真实用户的。

    2. 时间显示不对。

    解决方法:

    1.第一个问题

    继续使用命令

    $ man 5 utmp

    看到 ut_type中 USER_PROCESS表示的是已经登录的用户 ,那么第一个问题就解决了。

    2.第二个问题

    使用命令

    $ man -k time | grep transform

    看到ctime,使用命令查看ctime的使用方法

    $ man 3 ctime

    使用这个函数将 timeval转换成一个字符串并返回一个指针,那么第二个问题也解决了。

    who命令的编写---版本2

     1 #include <stdio.h>
     2 #include <utmp.h>
     3 #include <fcntl.h>
     4 #include <unistd.h>
     5 #include <time.h>
     6 
     7 void show_info(struct utmp *utbufp);
     8 void show_time(long timeval);
     9 int main()
    10 {
    11     struct utmp current_record;
    12     int utmp_fd;
    13     int reclen = sizeof(current_record);    
    14 
    15     utmp_fd = open(UTMP_FILE,O_RDONLY);    
    16     if(utmp_fd == -1)
    17     return -1;
    18 
    19     while( read(utmp_fd, &current_record,reclen) == reclen )
    20      show_info(&current_record);
    21     
    22     close(utmp_fd);
    23     return 0;
    24 }
    25 
    26 void show_info(struct utmp *utbufp)
    27 {
    28     if(utbufp->ut_type != USER_PROCESS)
    29     return;    
    30 
    31     printf("%-8.8s",utbufp->ut_name);
    32     printf(" ");
    33     printf("%-8.8s",utbufp->ut_line);
    34     printf(" ");
    35     show_time(utbufp->ut_time);
    36     printf(" ");
    37     printf("(%s)",utbufp->ut_host);
    38     printf("
    ");
    39 }
    40 
    41 void show_time(long timeval)
    42 {
    43     char *cp;
    44     
    45     cp = ctime(&timeval);
    46 
    47     printf("%12.12s",cp+4);
    48 
    49 }

    输出结果:

    这样一个简单的who命令就完成了。

    ------------------------------于2019/5/5更新---------------------

    改良who命令

    Linux---cp命令中,介绍了有关缓冲区和系统开销的知识,因此,我们可以改良自己编写的who命令。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <utmp.h>
    
    #define NRECS    16
    #define NULLUT    ((struct utmp*)NULL)
    #define UTSIZE  (sizeof(struct utmp))
    
    static char utmpbuf[NRECS * UTSIZE];
    static int num_recs;
    static int cur_rec;
    static int fd_utmp = -1;
    
    struct utmp* utmp_next();
    int utmp_reload();
    int utmp_open(char *filename);
    void utmp_close();
    
    
    
    int utmp_open(char *filename)
    {
        fd_utmp = open(filename , O_RDONLY);
        cur_rec =  0;
        num_recs = 0;
        return fd_utmp;
    }    
    
    
    
    struct utmp* utmp_next()
    {
        struct utmp* recp;
        if(fd_utmp == -1)
        {
            return NULLUT;
        }
        if(cur_rec == num_recs && utmp_reload() == 0)
        {
            return NULLUT;
        }
    
        recp = (struct utmp*) &utmpbuf[cur_rec * UTSIZE];
        cur_rec++;
        return recp;
    }
    
    int utmp_reload()
    {
        int aimt_read;
        aimt_read = read(fd_utmp, utmpbuf, NRECS * UTSIZE);
        num_recs = aimt_read / UTSIZE;
        cur_rec  = 0;
        return num_recs;
    
    }    
    
    
    void utmp_close()
    {
        if(fd_utmp != -1)
        close(fd_utmp);
    }

    编写一个增大缓冲区的库,调用的次数减少到原来的1/16。这样程序能够在更短的时间内完成。

     1 #include <stdio.h>
     2 #include <utmp.h>
     3 #include <fcntl.h>
     4 #include <unistd.h>
     5 #include <time.h>
     6 #include <sys/types.h>
     7 #include <stdlib.h>
     8 
     9 void show_info(struct utmp *utbufp);
    10 void show_time(long timeval);
    11 
    12 #define SHOWHOST
    13 
    14 int main()
    15 {
    16     struct utmp* utbufp , *utmp_next();
    17     if( utmp_open(UTMP_FILE) == -1)
    18     {
    19         perror(UTMP_FILE);
    20         exit(1);
    21     }    
    22 
    23     while( (utbufp = utmp_next()) != ((struct utmp *)NULL))
    24      show_info(utbufp);
    25     
    26     utmp_close();
    27     return 0;
    28 }
    29 
    30 void show_info(struct utmp *utbufp)
    31 {
    32     if(utbufp->ut_type != USER_PROCESS)
    33     return;    
    34 
    35     printf("%-8.8s",utbufp->ut_name);
    36     printf(" ");
    37     printf("%-8.8s",utbufp->ut_line);
    38     printf(" ");
    39     show_time(utbufp->ut_time);
    40     printf(" ");
    41     printf("(%s)",utbufp->ut_host);
    42     printf("
    ");
    43 }
    44 
    45 void show_time(long timeval)
    46 {
    47     char *cp;
    48     
    49     cp = ctime(&timeval);
    50 
    51     printf("%12.12s",cp+4);
    52 
    53 }

    本篇笔记自拜读《 Unix/Linux编程实践教程》

    我也推荐和我一样的初学者去拜读这本书,让你对linux有可下手的地方。

  • 相关阅读:
    CentOS 6.5系统使用yum方式安装LAMP环境
    省市区三级联动—PCASClass
    javascript进击(九)参考手册
    javascript进击(八)JSON
    javascript进击(七)Ajax
    javascript进击(六)Jquery
    javascript进击(五)JS对象
    javascript进击(四)HTML DOM
    javascript进击(三)简介
    javascript进击(一)简介
  • 原文地址:https://www.cnblogs.com/r1chie/p/10797216.html
Copyright © 2011-2022 走看看