我如何控制由 popen() 创建的管道?

How do I have control over the pipe created by popen()?

注意: 我知道我可以通过使用 fork 和也许 wait 来实现我所描述的,但我想了解如何 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 *对象又是"the pipe"?我可以访问 fp[0] & fp[1] 吗?

输出:

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

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

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

A "pipe" 只是一对连接的文件描述符...一个在 parent 进程中可用(即来自 popen 的 return 值),一个在child 过程。当您从 fp 变量读取时,您是从管道的一端读取(当 child 进程写入 stdout 时,它正在写入管道的另一端)。

is the child reading from the stream or the parent

当您 运行 fp = popen("date", "r") 时,您正在创建一个 uni-directional 管道。 parent 可以读取,child 可以写入(如果您指定 "w" 作为模式,则相反)。

您在此处明确阅读 pip:

fgets(buffer, BUFFER_SIZE, fp);

and how do I know what is executed by the sub-process

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

Furthermore, how do we know which end is for read and which is for write

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


is the whole purpose of popen (in my case, here) to redirect the output of a command to the parent process

popen 的目的是允许 child 进程和 parent 进程之间的通信。它创建一个单向管道,但您可以控制是 parent -> child 还是 child -> parent.

Is this what happens in the program I have provided? 1) popen opens a sub-process 2) The sub-process writes the output of the date command to the writing-end of the pipe 3) The parent process reads the read-end of the pipe(ie what the child has transmitted)?

没错。