2011-06-11 20 views
7

按照问题“How to get Linux distribution name and version?”,获得Linux发行版的名称和版本,这个工程:C++得到Linux版本的名称版本

lsb_release -a 

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

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

现在,要在C++中获得这些信息,Qt4的QProcess将是一个很好的选择,但由于我使用std C++开发没有Qt,所以我需要知道如何在标准C++中获得这些信息,即进程的stdout ,也是解析信息的一种方式。

Uptil now我试图使用来自here的代码,但是卡在函数read()中。通过包括头

#include <sys/utsname.h> 

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

int uname(struct utsname *buf); 

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 
    }; 

+0

?从C++开始外部过程?阅读其输出? ...请更具体,并显示你到目前为止。 – Mat 2011-06-11 11:41:33

+0

更新........... – yolo 2011-06-11 12:02:42

+0

找到答案http://stackoverflow.com/questions/6315666/c-get-linux-distribution-name-version/6316023#6316023 – yolo 2011-06-11 12:56:25

回答

0

从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; 
} 
+1

这一半时间不起作用,它只是挂起。任何想法为什么?另外,因为你永远不会释放内存泄漏,所以不会“内存泄漏”? – leetNightshade 2012-08-02 22:53:11

16

你可以简单的使用功能我错过了什么吗?

+4

其实这已经实现。我需要知道分发名称和版本,例如“Ubuntu的”或“Fedora的”等 – yolo 2011-06-11 11:59:45

+0

由于我的程序只在Ubuntu系统上运行,得到的答案与此一合并帮助我: http://askubuntu.com/a/517140/17800 – Stoffisimo 2016-10-12 13:01:00

0

有命名文件/ etc/和/ etc/发布其中有像您是否使用Ubuntu或Fedora等(这是什么OP澄清了他的问题所在)的信息。

+0

我使用Ubuntu 12 ,而这些文件不存在。所以如果它不是Linux的便携式解决方案,这看起来不是一个好的选择。 – leetNightshade 2013-01-11 17:48:45

+2

我发现'/ etc/lsb-release'和'/ etc/debian_version',有趣的是。我会将其添加到答案中。 – icedwater 2014-02-27 03:10:25

1
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] 
} 

它为您遇到的麻烦是什么我

+1

你如何从writepipe中读取lsb_release的输出?编程管是一个非常小的缓冲区,如果你的意思是写信并从中获得回报,你就不会认真。 – leetNightshade 2013-01-11 17:50:25