【问题标题】:How do I have control over the pipe created by popen()?如何控制 popen() 创建的管道?
【发布时间】:2020-08-14 20:39:53
【问题描述】:

注意:我知道我可以通过使用forkwait 来实现我所描述的,但我想了解popen 的工作原理以及如何使用它在两者之间进行通信进程。

我想使用popen创建一个子进程,然后在子进程中写入popen创建的管道,然后在父进程中,从管道中读取并输出消息。

这是我尝试过的:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

#define BUFFER_SIZE 105

int main(int argc, const char * argv[])
{
    FILE* fp;
    int status;
    char buffer[BUFFER_SIZE];

    fp = popen("date", "r"); // returns `FILE *` object (the same as a "stream", I think)
    if(fp == NULL) { printf("Eroare la deschidere cu `popen()`\n");} return -1; // or `EXIT_FAILURE`

    fgets(buffer, BUFFER_SIZE, fp); // ????? is this where I am reading from the pipe? 
                                    // `popen` returns a pointer to a stream, thus is it a `FILE *` object?
                                    // As such, is `fp` also the pipe? "pipe" == "stream" == `FILE *` object ?
    printf("I have read: %s", buffer); 

    status = pclose(fp);
    if(status == -1) { printf("`Eroare la inchiderea cu popen()`\n"); return -1;} // or `EXIT_FAILURE`

return 0; // or `EXIT_SUCCESS`?
}

另外,在这种情况下,哪个是管道? fp 既是 FILE * 对象又是“管道”?我可以访问fp[0]fp[1] 吗?

输出:

I have read: Thu Apr 30 16:29:05 EEST 2020

【问题讨论】:

  • popen 是一个标准的 C 函数。它与进程或 Unix 管道或 &lt;unistd.h&gt;&lt;sys/types.h&gt;&lt;sys/wait.h&gt; 无关。在内部,它可能会或可能不会使用这些 Unix 工具来实现。如果是,它将对程序员完全隐藏。
  • @n.'pronouns'm。您好,感谢您的回答!

标签: c unix process pipe popen


【解决方案1】:

我不完全清楚你在这里问什么,所以如果这个答案有误,请告诉我。

man popen 确认 popen 返回一个FILE *。它不是一个数组;没有fp[0]fp[1]

“管道”只是一对连接的文件描述符……一个在父进程中可用(即 popen 的返回值),一个在子进程中可用。当您从 fp 变量中读取时,您正在从管道的一端读取(当子进程写入 stdout 时,它正在写入管道的另一端)。

是从流中读取的子级还是父级

当您运行fp = popen("date", "r") 时,您正在创建一个单向管道。父母可以阅读,孩子可以写作(如果您将"w" 指定为模式,则相反)。

您在此处明确读取 pip:

fgets(buffer, BUFFER_SIZE, fp);

我怎么知道子进程执行了什么

子进程执行您告诉它的内容(在本例中为date)。

另外,我们怎么知道哪一端是读,哪一端是写

您可以使用popen 命令的第二个参数进行控制。


popen 的全部目的(在我的例子中,在这里)将命令的输出重定向到父进程

popen 的目的是允许子进程和父进程之间进行通信。它会创建一个单向管道,但您可以控制它是 parent -&gt; child 还是 child -&gt; parent

这是我提供的程序中发生的情况吗? 1) popen 打开一个子进程 2) 子进程将 date 命令的输出写入管道的写端 3) 父进程读取管道的读端(即子进程传输的内容) ?

没错。

【讨论】:

  • 嗨!并感谢您的回答!不,你没有错过这里的标记。我不确定以下事情;当我从fp 读取时:子进程是从流读取还是从父进程读取,我如何知道子进程执行了什么以及处理popen 时父进程执行了什么?此外,我们如何知道哪一端是read,哪一端是write;使用popen时,孩子总是回信给父母吗?
  • 根据我在互联网上找到的所有内容和您的答案来判断:popen(在我的情况下,在这里)的全部目的是将命令的输出重定向到父进程,这读取它(从管道)?这是我提供的程序中发生的情况吗? 1)popen打开一个子进程 2)子进程将date命令的输出写入管道的writing-end 3)父进程读取管道的读取端(即孩子传输的内容)?我想现在一切都清楚了。不过,如果您认为它们有用,请随时添加任何其他注释。
  • 我已经更新了答案,对您的 cmets 进行了一些回复。
  • 解释得很详细!现在一切都清楚多了。太感谢了!祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-09
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 2013-09-29
  • 2019-10-04
相关资源
最近更新 更多