从 Linux 中的 /proc 文件系统获取硬件信息
Get hardware information from /proc filesytem in Linux
我使用execv
到运行lshw
命令在C代码中获取CPU、磁盘和内存。但我想搜索另一种解决方案以从 /proc
或任何其他现有数据中获取这些信息。有什么建议吗?这是我的代码:
char *params[9] = {"/usr/bin/lshw", "-short", "-c", "disk",
"-c", "memory", "-c", "processor", 0}; //cmd params filled
execv(params[0], params);
Linux 命令:$ sudo lshw -short -c disk -c processor -c memory
$ sudo lshw -short -c disk -c processor -c memory
H/W path Device Class Description
======================================================
/0/0 memory 64KiB BIOS
/0/22 memory 16GiB System Memory
/0/22/0 memory DIMM Synchronous [empty]
/0/22/1 memory DIMM Synchronous [empty]
/0/22/2 memory 8GiB DIMM Synchronous 2133 MHz (0.5 ns)
/0/22/3 memory 8GiB DIMM Synchronous 2133 MHz (0.5 ns)
/0/2a memory 256KiB L1 cache
/0/2b memory 1MiB L2 cache
/0/2c memory 6MiB L3 cache
/0/2d processor Intel(R) Xeon(R) CPU D-1521 @ 2.40GHz
/0/1/0.0.0 /dev/sda disk 16GB SATADOM-SH 3IE3
/0/2/0.0.0 /dev/sdb disk 120GB Patriot Blaze
我有两个问题:
- 在哪里可以找到解析
/proc
中文件的指南以获取
这些硬件信息?
- 我是否需要跟踪
lshw
的源代码才能找到 lshw
的作用?
编辑:
Advanced Linux Programming 的第 7 章是解析 /proc
文件系统的指南。
1:要获取 CPU 负载,请使用此命令:
top -bn1 | grep load
这会给你这样的输出:
top - 12:26:20 up 35 min, 2 users, load average: 0.02, 0.01, 0.00
现在解析上述字符串的平均负载。
2:要获取内存信息,请使用此命令:
free -m
这会给你:
total used free shared buffers cached
Mem: 15926 308 15617 6 15 122
-/+ buffers/cache: 171 15755
Swap: 0 0 0
要获取磁盘信息,请使用:
df -H /home/test
这会给你:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 102G 5.4G 91G 6% /
现在从上面的结果中解析出你想要的内容。
获取硬件信息的最佳方法是使用 sysconf() 和 sysctl*() 函数(Mac OS X、freebsd、openbsd),以及 sysconf() 和 sysinfo() Linux。
解析 /proc/* 比调用 sysinfo( ) 或 sysconf( ) 更慢且更复杂
下面是一个小示例,为您提供有关 Mac OS X:
上处理器和内存的一些信息
#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main()
{
char *p = NULL;
size_t len;
sysctlbyname("hw.model", NULL, &len, NULL, 0);
p = malloc(len);
sysctlbyname("hw.model", p, &len, NULL, 0);
printf("%s\n", p);
/* CTL_MACHDEP variables are architecture dependent so doesn't work
for every one */
sysctlbyname("machdep.cpu.brand_string", NULL, &len, NULL, 0);
p = malloc(len);
sysctlbyname("machdep.cpu.brand_string", p, &len, NULL, 0);
printf("%s\n", p);
int64_t mem;
len = sizeof(mem);
sysctlbyname("hw.memsize", &mem, &len, NULL, 0);
printf("System Memory : %lld\n", mem);
return (0);
}
你必须阅读 man 3 sysctl,或者 Linux man 2 sysconf 和 man 2 sysinfo。
一个有趣的 link : http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system#Other
您可以计算 CPU 负载和使用情况,检索一些 sysctl 变量,然后自己计算(您可以在 google 上找到计算公式)。
But where to find the physical DIMM information as the report from $ sudo lshw -short -c memory ?
您可以在 C 程序中执行您的命令,将其保存为字符串,例如:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
char *strjoin(char *s1, char *s2, int n)
{
int i = strlen(s2);
int j = 0;
if ((s2 = realloc(s2, (i + n + 1))) == NULL)
perror(0);
while (j < n && s1[j])
{
s2[i] = s1[j];
i++;
j++;
}
s2[i] = 0;
return (s2);
}
int main()
{
pid_t father;
char buf[500] = {0};
char *str;
char *argv[5] = {"/usr/bin/lshw", "-short", "-c", "memory"};
int fd[2];
int ret;
if (pipe(fd) == -1)
{
perror(NULL);
return -1;
}
father = fork();
if (father == 0)
{
close(fd[1]);
while ((ret = read(fd[0], buf, 500)))
{
str = strjoin(buf, str, ret);
}
close(fd[0]);
}
else
{
close(fd[0]);
execv(argv[0], argv);
close(fd[1]);
wait(0);
}
wait(0);
printf("%s", str);
return 0;
}
(我没有在这段代码中检查所有函数的return,以免太长,但你应该在你的程序中这样做)。
这是一个解析文件 /proc/meminfo 以将我想要的 2 个字符串保存在双数组中,然后将它们打印出来的示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *f;
char *line = NULL;
ssize_t read;
size_t len = 0;
char **info;
int i = 0;
info = malloc(3 * sizeof(char*));
f = fopen("/proc/meminfo", "r");
while ((read = getline(&line, &len, f)) != -1)
{
if (strstr(line, "MemTotal") != NULL)
info[i] = strdup(line);
else if (strstr(line, "MemFree") != NULL)
info[i] = strdup(line);
i++;
}
info[i] = 0;
fclose(f);
i = 0;
while (info[i])
{
printf("%s", info[i]);
free (info[i]);
i++;
}
free (info);
return 0;
}
如果你想保存更多的字符串,在double array info中malloc more space,然后在read循环中用else if添加。您可以使用 /proc/ 中的任何文件来获取所需的信息。
通过阅读lshw
的源代码,发现lshw
从/sys/class/dmi/
读取原始数据。因为lshw
是用我不熟悉的CPP写的,有一个问题Where does dmidecode get the SMBIOS table?提到dmidecode.c
从/sys/class/dmi
读取原始数据与lshw
相同
这是dmidecode.c
中的定义
#define SYS_ENTRY_FILE "/sys/firmware/dmi/tables/smbios_entry_point"
#define SYS_TABLE_FILE "/sys/firmware/dmi/tables/DMI"
我从dmidecode.c
to get the CPU and memory information, and use lsscsi
中提取代码以获取磁盘信息。
感谢您的帮助。
我使用execv
到运行lshw
命令在C代码中获取CPU、磁盘和内存。但我想搜索另一种解决方案以从 /proc
或任何其他现有数据中获取这些信息。有什么建议吗?这是我的代码:
char *params[9] = {"/usr/bin/lshw", "-short", "-c", "disk",
"-c", "memory", "-c", "processor", 0}; //cmd params filled
execv(params[0], params);
Linux 命令:$ sudo lshw -short -c disk -c processor -c memory
$ sudo lshw -short -c disk -c processor -c memory
H/W path Device Class Description
======================================================
/0/0 memory 64KiB BIOS
/0/22 memory 16GiB System Memory
/0/22/0 memory DIMM Synchronous [empty]
/0/22/1 memory DIMM Synchronous [empty]
/0/22/2 memory 8GiB DIMM Synchronous 2133 MHz (0.5 ns)
/0/22/3 memory 8GiB DIMM Synchronous 2133 MHz (0.5 ns)
/0/2a memory 256KiB L1 cache
/0/2b memory 1MiB L2 cache
/0/2c memory 6MiB L3 cache
/0/2d processor Intel(R) Xeon(R) CPU D-1521 @ 2.40GHz
/0/1/0.0.0 /dev/sda disk 16GB SATADOM-SH 3IE3
/0/2/0.0.0 /dev/sdb disk 120GB Patriot Blaze
我有两个问题:
- 在哪里可以找到解析
/proc
中文件的指南以获取 这些硬件信息? - 我是否需要跟踪
lshw
的源代码才能找到lshw
的作用?
编辑:
Advanced Linux Programming 的第 7 章是解析 /proc
文件系统的指南。
1:要获取 CPU 负载,请使用此命令:
top -bn1 | grep load
这会给你这样的输出:
top - 12:26:20 up 35 min, 2 users, load average: 0.02, 0.01, 0.00
现在解析上述字符串的平均负载。 2:要获取内存信息,请使用此命令:
free -m
这会给你:
total used free shared buffers cached
Mem: 15926 308 15617 6 15 122
-/+ buffers/cache: 171 15755
Swap: 0 0 0
要获取磁盘信息,请使用:
df -H /home/test
这会给你:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 102G 5.4G 91G 6% /
现在从上面的结果中解析出你想要的内容。
获取硬件信息的最佳方法是使用 sysconf() 和 sysctl*() 函数(Mac OS X、freebsd、openbsd),以及 sysconf() 和 sysinfo() Linux。
解析 /proc/* 比调用 sysinfo( ) 或 sysconf( ) 更慢且更复杂
下面是一个小示例,为您提供有关 Mac OS X:
上处理器和内存的一些信息#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main()
{
char *p = NULL;
size_t len;
sysctlbyname("hw.model", NULL, &len, NULL, 0);
p = malloc(len);
sysctlbyname("hw.model", p, &len, NULL, 0);
printf("%s\n", p);
/* CTL_MACHDEP variables are architecture dependent so doesn't work
for every one */
sysctlbyname("machdep.cpu.brand_string", NULL, &len, NULL, 0);
p = malloc(len);
sysctlbyname("machdep.cpu.brand_string", p, &len, NULL, 0);
printf("%s\n", p);
int64_t mem;
len = sizeof(mem);
sysctlbyname("hw.memsize", &mem, &len, NULL, 0);
printf("System Memory : %lld\n", mem);
return (0);
}
你必须阅读 man 3 sysctl,或者 Linux man 2 sysconf 和 man 2 sysinfo。
一个有趣的 link : http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system#Other
您可以计算 CPU 负载和使用情况,检索一些 sysctl 变量,然后自己计算(您可以在 google 上找到计算公式)。
But where to find the physical DIMM information as the report from $ sudo lshw -short -c memory ?
您可以在 C 程序中执行您的命令,将其保存为字符串,例如:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
char *strjoin(char *s1, char *s2, int n)
{
int i = strlen(s2);
int j = 0;
if ((s2 = realloc(s2, (i + n + 1))) == NULL)
perror(0);
while (j < n && s1[j])
{
s2[i] = s1[j];
i++;
j++;
}
s2[i] = 0;
return (s2);
}
int main()
{
pid_t father;
char buf[500] = {0};
char *str;
char *argv[5] = {"/usr/bin/lshw", "-short", "-c", "memory"};
int fd[2];
int ret;
if (pipe(fd) == -1)
{
perror(NULL);
return -1;
}
father = fork();
if (father == 0)
{
close(fd[1]);
while ((ret = read(fd[0], buf, 500)))
{
str = strjoin(buf, str, ret);
}
close(fd[0]);
}
else
{
close(fd[0]);
execv(argv[0], argv);
close(fd[1]);
wait(0);
}
wait(0);
printf("%s", str);
return 0;
}
(我没有在这段代码中检查所有函数的return,以免太长,但你应该在你的程序中这样做)。
这是一个解析文件 /proc/meminfo 以将我想要的 2 个字符串保存在双数组中,然后将它们打印出来的示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *f;
char *line = NULL;
ssize_t read;
size_t len = 0;
char **info;
int i = 0;
info = malloc(3 * sizeof(char*));
f = fopen("/proc/meminfo", "r");
while ((read = getline(&line, &len, f)) != -1)
{
if (strstr(line, "MemTotal") != NULL)
info[i] = strdup(line);
else if (strstr(line, "MemFree") != NULL)
info[i] = strdup(line);
i++;
}
info[i] = 0;
fclose(f);
i = 0;
while (info[i])
{
printf("%s", info[i]);
free (info[i]);
i++;
}
free (info);
return 0;
}
如果你想保存更多的字符串,在double array info中malloc more space,然后在read循环中用else if添加。您可以使用 /proc/ 中的任何文件来获取所需的信息。
通过阅读lshw
的源代码,发现lshw
从/sys/class/dmi/
读取原始数据。因为lshw
是用我不熟悉的CPP写的,有一个问题Where does dmidecode get the SMBIOS table?提到dmidecode.c
从/sys/class/dmi
读取原始数据与lshw
相同
这是dmidecode.c
#define SYS_ENTRY_FILE "/sys/firmware/dmi/tables/smbios_entry_point"
#define SYS_TABLE_FILE "/sys/firmware/dmi/tables/DMI"
我从dmidecode.c
to get the CPU and memory information, and use lsscsi
中提取代码以获取磁盘信息。
感谢您的帮助。