LV05-07-Linux系统-01-系统信息获取

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

点击查看使用工具及版本
Windows windows11
Ubuntu Ubuntu16.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
SecureCRT Version 8.7.2 (x64 build 2214) - 正式版-2020年5月14日
开发板 正点原子 i.MX6ULL Linux阿尔法开发板
uboot NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)
linux内核 linux-4.15(NXP官方提供)
STM32开发板 正点原子战舰V3(STM32F103ZET6)
点击查看本文参考资料
参考方向 参考原文
------
点击查看相关文件下载
--- ---

一、系统信息

1. uname() 函数

1.1 函数说明

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

1
2
3
4
5
/* 需包含的头文件 */
#include <sys/utsname.h>

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

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

【函数参数】

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

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

1
2
3
4
5
6
7
8
9
10
11
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

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

1
2
3
4
5
6
/* 需要包含的头文件 */
#include <sys/utsname.h>

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

【注意事项】none

1.2 使用实例

点击查看实例
test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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;
}

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

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

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

1
2
3
4
5
操作系统名称: 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命令查看该函数的帮助手册。

1
2
3
4
5
/* 需包含的头文件 */
#include <sys/sysinfo.h>

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

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

【函数参数】

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct sysinfo
{
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* Swap space still available */
unsigned short procs; /* Number of current processes */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

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

1
2
3
4
5
6
/* 需要包含的头文件 */
#include <sys/sysinfo.h>

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

【注意事项】none

2.2 使用实例

点击查看实例
test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#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;
}

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

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

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

1
2
3
4
5
6
7
8
9
10
11
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命令查看该函数的帮助手册。

1
2
3
4
5
/* 需包含的头文件 */
#include <unistd.h>

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

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

【函数参数】

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

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

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

1
2
3
4
5
6
/* 需要包含的头文件 */
#include <unistd.h>

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

【注意事项】none

3.2 使用实例

点击查看实例
test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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;
}

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

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

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

1
hostname=vm

4. gethostname() 函数

4.1 函数说明

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

1
2
3
4
5
/* 需包含的头文件 */
#include <unistd.h>

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

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

【函数参数】

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

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

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

1
2
3
4
5
6
7
/* 需要包含的头文件 */
#include <unistd.h>

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

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

4.2 使用实例

点击查看实例
test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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;
}

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

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

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

1
2
3
4
5
6
hostname=vm
hostname=fanhua

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

5. sysconf() 函数

5.1 函数说明

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

1
2
3
4
5
/* 需包含的头文件 */
#include <unistd.h>

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

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

【函数参数】

  • nameint类型,指定了要获取配置信息的编号。
点击查看 name 可取的值

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

_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。否则返回的值便是对应的配置值。

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

1
2
3
4
5
/* 需要包含的头文件 */
#include <unistd.h>

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

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

5.2 使用实例

点击查看实例
test.c
1
2
3
4
5
6
7
8
9
10
11
12
#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;
}

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

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

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

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