【问题标题】:Stdout being not read using "popen" and "read" functions不使用“popen”和“read”函数读取标准输出
【发布时间】:2016-09-28 11:25:26
【问题描述】:

我有一个 c++ 代码试图运行 losetup /dev/loop* 并解析终端返回的内容。

代码就是这样

char cmd[32] = {0, };
sprintf(cmd, "losetup /dev/loop%d", i);
FILE *fp;
fp = popen(cmd,"r");
char buf[1024];
read(fileno(fp), buf, 123);
printf("After read: %s\n", buf);

发生了两种不同的事情。

当loop设备设置好后,输出是这样的:

After read: /dev/loop0: [0802] ...Remaining ommitted

这是我想要和期待的。

但是,当循环设备没有正确设置时,输出是这样的:

loop: can't get info on device /dev/loop1: No such device or address
After read:

如您所见,“buf”为 NULL,而应该在“buf”内部的标准输出只是在终端中打印出来。我不仅需要在设置循环设备时读取输出,还需要在未设置时读取输出。那么,有人可以解释一下如何解决这个问题,以便我可以存储两种情况的标准输出吗?

PS。我用“pipe”、“fgets”和“getline”尝试了“dup2”,它们都以类似的方式失败了。

【问题讨论】:

  • 我怀疑失败的案例打印在标准错误上,而不是标准输出上。
  • 如果是这种情况,如果我运行fileno(fp),我不应该得到2吗?我得到 3。
  • buf 不是NULL,它是空的。 (它不能是NULL,因为它是一个数组。)您还应该检查read的返回值以确定它是否成功; AFAICT 当你失败时buf 为空的事实完全是巧合。
  • 如果在命令末尾添加2>&1,则stderr将被重定向到stdout。

标签: c++ linux terminal


【解决方案1】:

管道只从标准输入到标准输出。

等错误信息
loop: can't get info on device /dev/loop1: No such device or address

转到标准错误。您可以通过将传递给popen的命令中的标准错误重定向来解决此问题,例如,

sprintf(cmd, "losetup /dev/loop%d 2>&1", i);

因为它是一个 shell 命令(并且 shell 允许您进行重定向)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    相关资源
    最近更新 更多