我有以下代码来查找我正在使用的 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。还有,有没有什么办法可以不让上面的错误显示在屏幕上呢?
最佳答案
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
来阅读更有意义来自磁盘上已存在的文件。
关于c - 防止 popen() 在 stderr 上显示错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32323126/