我有以下代码来查找我正在使用的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。另外,有没有办法防止上面的错误显示在屏幕上?
答案 0 :(得分:5)
popen
是一个更适合访问子进程输出的函数,而不是简单地访问文件内容。为此,您应该使用fopen
。 fopen
将文件路径和模式作为参数,因此您需要做的就是将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
来读取已存在的文件就更有意义了。磁盘。