C++ 获取 linux 发行版名称\版本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6315666/
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-08-05 04:27:08  来源:igfitidea点击:

C++ get linux distribution name\version

c++linuxdistribution

提问by yolo

According to the question " How to get Linux distribution name and version?", to get the linux distro name and version, this works:

根据问题“如何获取 Linux 发行版名称和版本?”,要获取 linux 发行版名称和版本,这是有效的:

lsb_release -a

On my system, it shows the needed output:

在我的系统上,它显示了所需的输出:

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 9.10
Release:    9.10
Codename:   karmic

Now, to get this info in C++, Qt4's QProcess would be a great option but since I am developing without Qt using std c++, I need to know how to get this info in standard C++, i.e. the stdout of the process, and also a way to parse the info.

现在,要在 C++ 中获取此信息,Qt4 的 QProcess 将是一个不错的选择,但由于我使用 std c++ 在没有 Qt 的情况下进行开发,因此我需要知道如何在标准 C++ 中获取此信息,即进程的 stdout,以及解析信息的方法。

Uptil now I am trying to use code from herebut am stuck on function read().

直到现在我都在尝试使用这里的代码,但卡在函数read() 上。

采纳答案by yolo

Got it from cplusplus.com forums, a simple call GetSystemOutput("/usr/bin/lsb_release -a")works.

从 cplusplus.com 论坛得到它,一个简单的调用就GetSystemOutput("/usr/bin/lsb_release -a")可以了。

char* GetSystemOutput(char* cmd){
        int buff_size = 32;
    char* buff = new char[buff_size];

        char* ret = NULL;
        string str = "";

    int fd[2];
    int old_fd[3];
    pipe(fd);


        old_fd[0] = dup(STDIN_FILENO);
        old_fd[1] = dup(STDOUT_FILENO);
        old_fd[2] = dup(STDERR_FILENO);

        int pid = fork();
        switch(pid){
                case 0:
                        close(fd[0]);
                        close(STDOUT_FILENO);
                        close(STDERR_FILENO);
                        dup2(fd[1], STDOUT_FILENO);
                        dup2(fd[1], STDERR_FILENO);
                        system(cmd);
                        //execlp((const char*)cmd, cmd,0);
                        close (fd[1]);
                        exit(0);
                        break;
                case -1:
                        cerr << "GetSystemOutput/fork() error\n" << endl;
                        exit(1);
                default:
                        close(fd[1]);
                        dup2(fd[0], STDIN_FILENO);

                        int rc = 1;
                        while (rc > 0){
                                rc = read(fd[0], buff, buff_size);
                                str.append(buff, rc);
                                //memset(buff, 0, buff_size);
                        }

                        ret = new char [strlen((char*)str.c_str())];

                        strcpy(ret, (char*)str.c_str());

                        waitpid(pid, NULL, 0);
                        close(fd[0]);
        }

        dup2(STDIN_FILENO, old_fd[0]);
        dup2(STDOUT_FILENO, old_fd[1]);
        dup2(STDERR_FILENO, old_fd[2]);

    return ret;
}

回答by Alok Save

You can simply use the function:

您可以简单地使用该功能:

int uname(struct utsname *buf);

by including the header

通过包含标题

#include <sys/utsname.h>

It already returns the name & version as a part of the structure:

它已经将名称和版本作为结构的一部分返回:

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

Am I missing something?

我错过了什么吗?

回答by Scott C Wilson

There are files named /etc/versionand /etc/releasewhich have information like whether you're using Ubuntu or Fedora, etc. (which is what the OP clarified his question to be).

有名为 /etc/ version和 /etc/ release 的文件,其中包含诸如您使用的是 Ubuntu 还是 Fedora 等信息(这是 OP 澄清他的问题的内容)。

回答by frp

int writepipe[2];
if (pipe(writepipe) < 0) {
  perror("pipe");
  return 1;
}
int ret = fork();
if (ret < 0) {
  perror("fork");
  return 1;
}
else if (ret == 0) // child process
{
  dup2(writepipe[1],1); // set writepipe[1] as stdout
  // close fds
  close(writepipe[0]);
  close(writepipe[1]);
  execlp("lsb_release","lsb_release","-a",NULL); //TODO: Error checking
}
else // parent process
{
  int status;
  waitpid(ret,&status,0); //TODO: Error checking
  //do what you need
  //read output of lsb_release from writepipe[0]
}

It works for me

这个对我有用

回答by adnan kamili

For recent linux distros you can use following to get the OS info. The output is pretty standard and can be parsed using following spec:

对于最近的 linux 发行版,您可以使用以下内容来获取操作系统信息。输出非常标准,可以使用以下规范进行解析:

https://www.freedesktop.org/software/systemd/man/os-release.html

https://www.freedesktop.org/software/systemd/man/os-release.html

cat /etc/os-release

Sample outputs:

示例输出:

NAME=Fedora
VERSION="27 (Twenty Seven)"
ID=fedora
VERSION_ID=27
PRETTY_NAME="Fedora 27 (Twenty Seven)"

NAME="Ubuntu"
VERSION="16.04.4 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.4 LTS"
VERSION_ID="16.04"

NAME="Arch Linux"
PRETTY_NAME="Arch Linux"
ID=arch
ID_LIKE=archlinux
ANSI_COLOR="0;36"

回答by codesniffer

Personally I like the the uname solution posted by @Alok Slav, but in case it helps someone who needs to use a command-line utility to get the info, consider using popen.

我个人喜欢@Alok Slav 发布的 uname 解决方案,但如果它可以帮助需要使用命令行实用程序获取信息的人,请考虑使用popen