Skip to content

LV005-系统信息获取

本文主要是用C语言获取Linux系统信息的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

一、系统信息

1. uname() 函数

1.1 函数说明

linux下可以使用man 2 uname命令查看该函数的帮助手册。

c
/* 需包含的头文件 */
#include <sys/utsname.h>

/* 函数声明 */
int uname(struct utsname *buf);

函数说明】该函数是一个系统调用,可以用于获取系统的一些信息。

函数参数

  • bufstruct utsname类型结构体指针变量,指向一个存储系统信息的struct utsname结构体类型对象,该结构体类型的成员都是char类型的字符串。

在使用man查看帮助手册的时候,有struct utsname结构体的原型:

c
struct utsname
{
	char sysname[];    /* Operating system name (e.g., "Linux") */
	char nodename[];   /* Name within "some implementation-defined network" */
	char release[];    /* Operating system release (e.g., "2.6.28") */
	char version[];    /* Operating system version */
	char machine[];    /* Hardware identifier */
#ifdef _GNU_SOURCE
	char domainname[]; /* NIS or YP domain name */
#endif
};

成员说明如下:

sysname当前操作系统的名称
nodename网络上的名称(主机名)
release操作系统内核版本
version操作系统发行版本
machine硬件架构类型
domainname当前域名
【**返回值**】`int`类型,成功返回`0`,失败返回`-1`,并设置`errno`。

使用格式】一般情况下基本使用格式如下:

c
/* 需要包含的头文件 */
#include <sys/utsname.h>

/* 至少应该有的语句 */
struct utsname os_info;
uname(&os_info);

注意事项none

1.2 使用实例

c
#include <stdio.h>
#include <sys/utsname.h>

int main(int arc, char *argv[])
{
	struct utsname os_info;
	int ret; /* 获取信息 */
	ret = uname(&os_info);
	if (ret == -1)
	{
		perror("uname error");
		return -1;
	}

	/* 打印信息 */
	printf("操作系统名称: %s\n", os_info.sysname);
	printf("主机名: %s\n", os_info.nodename);
	printf("内核版本: %s\n", os_info.release);
	printf("发行版本: %s\n", os_info.version);
	printf("硬件架构: %s\n", os_info.machine);
	return 0;
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
操作系统名称: Linux
主机名: vm
内核版本: 5.11.0-49-generic
发行版本: #55-Ubuntu SMP Wed Jan 12 17:36:34 UTC 2022
硬件架构: x86_64

2. sysinfo() 函数

2.1 函数说明

linux下可以使用man 2 sysinfo命令查看该函数的帮助手册。

c
/* 需包含的头文件 */
#include <sys/sysinfo.h>

/* 函数声明 */
int sysinfo(struct sysinfo *info);

函数说明】该函数是一个系统调用,可以用于获取系统的一些相关信息。

函数参数

  • infostruct sysinfo类型结构体指针变量,指向一个存储系统相关信息的struct sysinfo结构体类型对象。

在使用man查看帮助手册的时候,有struct sysinfo结构体的原型:

c
struct sysinfo
{
	long uptime;             /* 启动到现在经过的时间 */
	unsigned long loads[3];  /* 1, 5, and 15 minute load averages */
	unsigned long totalram;  /* 总的可用的内存大小 */
	unsigned long freeram;   /* 还未被使用的内存大小 */
	unsigned long sharedram; /* 共享的存储器的大小 */
	unsigned long bufferram; /* 共享的存储器的大小 */
	unsigned long totalswap; /* 交换区大小 */
	unsigned long freeswap;  /* 还可用的交换区大小 */
	unsigned short procs;    /* 当前进程数目 */
	unsigned long totalhigh; /* 总的高内存大小 */
	unsigned long freehigh;  /* 可用的高内存大小 */
	unsigned int mem_unit;   /* 以字节为单位的内存大小 */
	char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
};

返回值int类型,成功返回0,失败返回-1,并设置errno

使用格式】一般情况下基本使用格式如下:

c
/* 需要包含的头文件 */
#include <sys/sysinfo.h>

/* 至少应该有的语句 */
struct sysinfo sys_info;
sysinfo(&sys_info);

注意事项none

2.2 使用实例

c
#include <stdio.h>
#include <sys/sysinfo.h>

int main(int arc, char *argv[])
{
	struct sysinfo sys_info;
	int ret; /* 获取信息 */
	ret = sysinfo(&sys_info);
	if (ret == -1)
	{
		perror("sysinfo error");
		return -1;
	}

	/* 打印信息 */
	printf("uptime: %ld\n", sys_info.uptime);
	printf("totalram: %lu\n", sys_info.totalram);
	printf("freeram: %lu\n", sys_info.freeram);
	printf("sharedram: %lu\n", sys_info.sharedram);
	printf("bufferram: %lu\n", sys_info.bufferram);
	printf("totalswap: %lu\n", sys_info.totalswap);
	printf("freeswap: %lu\n", sys_info.freeswap);
	printf("procs: %u\n", sys_info.procs);
	printf("totalhigh: %lu\n", sys_info.totalhigh);
	printf("freehigh: %lu\n", sys_info.freehigh);
	printf("mem_unit: %d\n", sys_info.mem_unit);
	return 0;
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
uptime: 9035
totalram: 4083724288
freeram: 1898512384
sharedram: 38412288
bufferram: 110936064
totalswap: 1218854912
freeswap: 1218854912
procs: 532
totalhigh: 0
freehigh: 0
mem_unit: 1

3. gethostname() 函数

3.1 函数说明

linux下可以使用man 2 gethostname命令查看该函数的帮助手册。

c
/* 需包含的头文件 */
#include <unistd.h>

/* 函数声明 */
int gethostname(char *name, size_t len);

函数说明】该函数是一个系统调用,可以用于获取Linux系统的主机名称,功能其实与struct utsname数据结构体中的nodename成员变量一样。

函数参数

  • namechar类型指针变量,指向用于存放主机名字符串的内存缓冲区。
  • lensize_t类型,表示缓冲区的长度。

返回值int类型,成功返回0,失败返回-1,并设置errno

使用格式】一般情况下基本使用格式如下:

c
/* 需要包含的头文件 */
#include <unistd.h>

/* 至少应该有的语句 */
char hostname[20];
gethostname(hostname, sizeof(hostname));

注意事项none

3.2 使用实例

c
#include <stdio.h>
#include <unistd.h> 
#include <string.h>

int main(int arc, char *argv[])
{
	char hostname[20];
	int ret;
	memset(hostname, 0, sizeof(hostname));
	ret = gethostname(hostname, sizeof(hostname));
	if (ret == -1)
	{
		perror("gethostname error");
		return -1;
	}
	printf("hostname=%s\n", hostname);
	return 0;
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
hostname=vm

4. gethostname() 函数

4.1 函数说明

linux下可以使用man 2 gethostname命令查看该函数的帮助手册。

c
/* 需包含的头文件 */
#include <unistd.h>

/* 函数声明 */
int sethostname(const char *name, size_t len);

函数说明】该函数是一个系统调用,可以用于设置Linux系统的主机名称。

函数参数

  • namechar类型指针变量,指向用于存放要设置的主机名字符串的内存缓冲区。
  • lensize_t类型,表示缓冲区的长度。

返回值int类型,成功返回0,失败返回-1,并设置errno

使用格式】一般情况下基本使用格式如下:

c
/* 需要包含的头文件 */
#include <unistd.h>

/* 至少应该有的语句 */
char hostname[20];
strcpy(hostname, "fanhua");
sethostname(hostname, sizeof(hostname));

注意事项】必须在root用户运行才会生效,否则会提示没有操作权限,并且重启后主机名会恢复原来的名称。

4.2 使用实例

c
#include <stdio.h>
#include <unistd.h> 
#include <string.h>

int main(int arc, char *argv[])
{
	char hostname[20];
	int ret;
	memset(hostname, 0, sizeof(hostname));
	ret = gethostname(hostname, sizeof(hostname));
	if (ret == -1)
	{
		perror("gethostname error");
		return -1;
	}
	printf("hostname=%s\n", hostname);
	
	strcpy(hostname, "fanhua");
	ret = sethostname(hostname, sizeof(hostname));
	if (ret == -1)
	{
		perror("sethostname error");
		return -1;
	}
	memset(hostname, 0, sizeof(hostname));
	ret = gethostname(hostname, sizeof(hostname));
	if (ret == -1)
	{
		perror("gethostname error");
		return -1;
	}
	printf("hostname=%s\n", hostname);
	return 0;
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
hostname=vm
hostname=fanhua

# 在非 root 下运行的话,会有如下信息
hostname=vm
sethostname error: Operation not permitted

5. sysconf() 函数

5.1 函数说明

linux下可以使用man 3 sysconf命令查看该函数的帮助手册。

c
/* 需包含的头文件 */
#include <unistd.h>

/* 函数声明 */
long sysconf(int name);

函数说明】该函数是一个库函数,可在获取系统运行时的一些配置信息。

函数参数

  • nameint类型,指定了要获取配置信息的编号。

在使用man查看帮助手册的时候,会有大量的宏定义表示系统的配置信息,这里列举几个常用的name的值:

_SC_ARG_MAXexec族函数的参数的最大长度
_SC_CHILD_MAX每个用户的最大并发进程数,也就是同一个用户可以同时运行的最大进程数。
_SC_HOST_NAME_MAX 主机名的最大长度。
_SC_LOGIN_NAME_MAX登录名的最大长度。
_SC_CLK_TCK每秒时钟滴答数,也就是系统节拍率。
_SC_OPEN_MAX一个进程可以打开的最大文件数。
_SC_PAGESIZE系统页大小(page size)。
_SC_TTY_NAME_MAX终端设备名称的最大长度。
【**返回值**】`long`类型,若指定的参数`name`为无效值,则返回`-1`,并会将`errno`设置为`EINVAL`。如果`name`对应一个最大或最小限制,并且该限制是不确定的,则返回`-1`并且不更改`errno`。否则返回的值便是对应的配置值。

使用格式】一般情况下基本使用格式如下:

c
/* 需要包含的头文件 */
#include <unistd.h>

/* 至少应该有的语句 */
sysconf(_SC_TTY_NAME_MAX);

注意事项】返回值为long类型,使用printf打印时,需要使用%ld

5.2 使用实例

c
#include <stdio.h>
#include <unistd.h>

int main(int arc, char *argv[])
{
	printf("每个用户的最大并发进程数: %ld\n", sysconf(_SC_CHILD_MAX));
	printf("主机名最大长度: %ld\n", sysconf(_SC_HOST_NAME_MAX));
	printf("系统节拍率: %ld\n", sysconf(_SC_CLK_TCK));
	printf("系统页大小: %ld\n", sysconf(_SC_PAGESIZE));
	printf("一个进程可以打开的最大文件数: %ld\n", sysconf(_SC_OPEN_MAX));
	return 0;
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
每个用户的最大并发进程数: 15308
主机名最大长度: 64
系统节拍率: 100
系统页大小: 4096
一个进程可以打开的最大文件数: 1024