c - 使用 popen 和 pclose 时的问题

标签 c shell unix

我有一个使用popenpclose 的程序:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>
int main(void)
{
    FILE *fp = NULL;
    int ret_val = 0;

    fp = popen("ls *", "r");
    if (NULL == fp)
    {
        printf("popen error\n");
        return 1;
    }

    ret_val = pclose(fp);
    if (-1 == ret_val)
    {
        printf("pclose error\n");
        return 1;
    }
    else
    {
        printf("%d,%d,%d\n",ret_val, WIFEXITED(ret_val), WEXITSTATUS(ret_val));
    }
    return 0;
}

程序的输出是:

./test
Broken Pipe
36096,1,141

我的问题是:

  1. 为什么会出现“Broken pipe”?
  2. 为什么退出状态代码是 141?我认为执行了“ls *” 成功,因此退出状态应为 0。

最佳答案

  • ls 显示“Broken pipe”,因为 SIGPIPE 信号是 提出。
  • SIGPIPE 被引发,因为 ls 正试图输出到一个关闭的管道。
  • 管道已关闭,因为您的程序在 popen() 之后立即调用了 pclose()

pclose 的这种行为可以通过阅读 the documentation 得到进一步理解。 .基本上,pclose 将:

  1. 关闭由 popen() 调用打开的流。
  2. 等待命令终止。
  3. 返回命令的终止状态。

由于它关闭流然后等待命令终止,ls 有时可以尝试在之后写入流关闭因此导致上述情况。

此外,正如 kingsindian 所指出的,SIGPIPE 可能并不总是被提升。这是因为该命令实际上可以在主进程调用 pclose() 之前 完成其工作。由于这种行为是不可预测的,我建议实现一些同步。您总是想确切地知道您的程序在任何时候都处于什么状态。

附带说明一下,管道是用于进程间通信的。如果您的主进程只是 打开和关闭一个管道,您最好使用fork()exec()

关于c - 使用 popen 和 pclose 时的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15564014/

相关文章:

c - 替换句子中的多个空格

linux - 遇到特殊字符时将文件拆分为多个

c - 读取 C 中的 .dat 文件丢失/重复记录

c - 为什么打开 FIFO 时进程会被阻塞

c - FindResource 工作,LoadBitmap 不工作,从磁盘工作的 LoadImage

linux - 如何在文件中的特定列中搜索 shell 中的字符串?

shell - 从 makefile 传递 shell 脚本中的参数并取回结果?

c++ - 将 unix 时间转换为人类可读的格式

linux - 如何使 find 和 printf 在 bash 脚本中工作

C 以字节 block 读取文件