bash 在 C 中获取 Linux 系统信息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23323438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:19:11  来源:igfitidea点击:

Get Linux system information in C

clinuxbash

提问by user3574984

I have to check Linux system information. I can execute system commands in C, but doing so I create a new process for every one, which is pretty expensive. I was wondering if there is a way to obtain system information without being forced to execute a shell command. I've been looking around for a while and I found nothing. Actually, I'm not even sure if it's more convenient to execute commands via Bash calling them from my C program or find a way to accomplish the tasks using only C.

我必须检查Linux系统信息。我可以在 C 中执行系统命令,但是这样做我为每个人创建了一个新进程,这非常昂贵。我想知道是否有一种方法可以在不强制执行 shell 命令的情况下获取系统信息。我已经环顾了一段时间,但什么也没找到。实际上,我什至不确定是通过 Bash 从我的 C 程序中调用它们来执行命令还是找到一种仅使用 C 来完成任务的方法更方便。

回答by Tom van der Woerdt

Linux exposes a lotof information under /proc. You can read the data from there. For example, fopenthe file at /proc/cpuinfoand read its contents.

Linux的暴露了很多的信息下/proc。您可以从那里读取数据。例如,fopen文件位于/proc/cpuinfo并读取其内容。

回答by NlightNFotis

A presumably less known (and more complicated) way to do that, is that you can also use the api interface to sysctl. To use it under Linux, you need to #include <unistd.h>, #include <linux/sysctl.h>. A code example of that is available in the man page:

一种可能鲜为人知(且更复杂)的方法是,您还可以使用 api 接口来sysctl. 要在 Linux 下使用它,您需要#include <unistd.h>, #include <linux/sysctl.h>手册页中提供了一个代码示例

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/sysctl.h>

int _sysctl(struct __sysctl_args *args );

#define OSNAMESZ 100

int
main(void)
{
    struct __sysctl_args args;
    char osname[OSNAMESZ];
    size_t osnamelth;
    int name[] = { CTL_KERN, KERN_OSTYPE };

   memset(&args, 0, sizeof(struct __sysctl_args));
    args.name = name;
    args.nlen = sizeof(name)/sizeof(name[0]);
    args.oldval = osname;
    args.oldlenp = &osnamelth;

   osnamelth = sizeof(osname);

   if (syscall(SYS__sysctl, &args) == -1) {
        perror("_sysctl");
        exit(EXIT_FAILURE);
    }
    printf("This machine is running %*s\n", osnamelth, osname);
    exit(EXIT_SUCCESS);
}

However, the man page linked also notes:

但是,链接的手册页还指出:

Glibc does not provide a wrapper for this system call; call it using syscall(2). Or rather... don't call it: use of this system call has long been discouraged, and it is so unloved that it is likely to disappear in a future kernel version. Since Linux 2.6.24, uses of this system call result in warnings in the kernel log. Remove it from your programs now; use the /proc/sys interface instead.

This system call is available only if the kernel was configured with the CONFIG_SYSCTL_SYSCALL option.

Glibc 没有为这个系统调用提供包装器;使用 syscall(2) 调用它。或者更确切地说......不要调用它:长期以来一直不鼓励使用这个系统调用,它是如此不受欢迎,以至于它可能会在未来的内核版本中消失。自 Linux 2.6.24 起,使用此系统调用会导致内核日志中出现警告。立即将其从您的程序中删除;改用 /proc/sys 接口。

仅当内核配置了 CONFIG_SYSCTL_SYSCALL 选项时,此系统调用才可用。

Please keep in mind that anything you can do with sysctl(), you can also just read()from /proc/sys. Also note that I do understand that the usefulness of that syscall is questionable, I just put it here for reference.

请记住,您可以使用的任何内容sysctl(),也可以read()仅从/proc/sys. 另请注意,我确实理解该系统调用的用处值得怀疑我只是将其放在这里以供参考