Linux下编写Who命令

Who命令可以显示登录系统的用户信息。

1、查看who命令相关内容

通过联机手册,可以查询到who命令的详解。在终端输入man who,在Ubuntu 14.04 系统上,在DESCRIPTION可以看到如下所示的内容。


即登录的信息是放在/var/run/utmp 、/var/log/wtmp中,运行who命令后,从utmp文件中读取信息。因此,我们继续查看utmp文件是什么。

2、查看utmp

运用man命令的关键词搜索功能,在终端输入man -k utmp, 可以看到以下内容。

Linux下编写Who命令_第1张图片

我们可以看到utmp(5) 这一行与登录信息有关,接下来查看该部分。在终端输入man 5 utmp,在description处可以看到utmp的具体介绍。utmp中存放了一系列的结构体,并且声明在头文件中。utmp中的数据结构如下图所示。

Linux下编写Who命令_第2张图片

结构体中存放了用户名、tty、时间等信息。其中值得注意的是时间信息。为了将32位操作系统与64位操作系统保持一致,在这里通过一个宏定义来进行两种设置。我的操作系统是64位的,所以看64位处,即定义了一个ut_tv的结构体,里面包含了两个32位数,一个表示秒数,一个表示微妙数。unix中的时间表示是从1970年1月1日0时开始到所求时间所经过的秒数。所以我们还需要将秒数换算成时间,经过搜索,发现使用linux中的ctime()函数就可以实现。

3、函数一览表

函数名 open
目标     打开一个文件
头文件 #include< fcntl.h >
函数原型 int fd = open( char* name, int how )
参数

name 文件名

how O_REONLY, O_WRONLY, O_RDWR

返回值

-1 错误

int 成功返回文件描述符

函数名 read
目标 从文件把数据读取到缓冲区
头文件 #include< unistd.h >
函数原型 ssize_t numread = read( int fd, void* buf, size_t qty )
参数

fd 文件描述符

buf 目的缓冲区

要读取的字节数

返回值

-1 错误

numread 读取的字节数

函数名 close
目标 关闭文件
头文件 #include
函数原型 int res = close( int fd )
参数 fd 文件描述符
返回值

-1 遇到错误

0 成功关闭


函数名 ctime()
目标 将秒数转换为时间
头文件 #include
函数原型 char* res = ctime( const time_t *timep)
参数 time_t (实际上是long int)
返回值 char *

4、代码

#include 
#include 
#include 
#include 
#include 
#include 
int show_info(struct utmp* utbuf);
void show_time(time_t);
int main(){
  int fd = open(UTMP_FILE, O_RDONLY);
  if( fd == -1){
    perror( UTMP_FILE );
    exit( 1 );
  }
  struct utmp cur_record;
  int len = sizeof(cur_record);
  while( read(fd, &cur_record, len) == len ){
    show_info( &cur_record);
  }
  close(fd);
  return 0;
}
int show_info(struct utmp* utbuf){
  printf(" %-8.8s ", utbuf->ut_user); //登录名
  printf(" ");
  printf(" %-8.8s ", utbuf->ut_line);//tty
  printf(" ");
  //char* cp = ctime(&((utbuf->ut_tv).tv_sec));
  time_t time = (utbuf->ut_tv).tv_sec;
  show_time(time);
  printf("\n");
  return 0;
}
void show_time(time_t tm){
  char* cp;
  cp = ctime(&tm);
  printf(" %20.20s", cp);
}


你可能感兴趣的:(初学Linux)