防止popen()在stderr上显示错误

时间:2015-09-01 03:36:51

标签: c popen stderr

我有以下代码来查找我正在使用的Linux发行版的发行版。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{

    return print_osinfo();
}

int print_osinfo()
{
    FILE *fp;
    extern FILE* popen();
    char buffer[128];
    int index = 0;

    memset(buffer,0,sizeof(buffer));
    fp = popen("/etc/centos-release", "r");
    if(!fp)
    {
        pclose(fp);
        fp = popen("/etc/redhat-release", "r");
        if(!fp)
        {
            pclose(fp);
            return 1;
        }
    }
    while(fgets(buffer, sizeof(buffer), fp)!= NULL)
    {
        printf("%s\n",buffer);
    }
    pclose(fp);
    return 0;
}

如果我在Ubuntu 14.04上运行上面的代码,我会收到以下错误。

sh: 1: /etc/centos-release: not found

我无法理解为什么它不会尝试打开redhat-release然后返回-1。另外,有没有办法防止上面的错误显示在屏幕上?

1 个答案:

答案 0 :(得分:5)

popen是一个更适合访问子进程输出的函数,而不是简单地访问文件内容。为此,您应该使用fopenfopen将文件路径和模式作为参数,因此您需要做的就是将popen替换为fopen,它应该可以正常工作。

如果你真的想使用popen,它需要一个shell命令作为它的第一个参数,而不是文件名。请尝试使用popen("cat /etc/centos-release","r");

现在,您可能有点困惑,因为这两个函数都返回FILE指针。 fopen返回指向您作为参数传递的文件的指针。但是,popen返回一个指向您传递给它的命令输出的管道,C看作FILE指针。这是因为,在C中,所有i / o都是文件访问; C与外界的唯一联系是通过文件。因此,为了传递一些shell命令的输出,popen创建C在内存中看到的FILE,包含所述shell命令的输出。因为运行一个完整的其他程序(shell命令)只是为了完成fopen做得非常好而非常荒谬,所以仅使用fopen来读取已存在的文件就更有意义了。磁盘。