将exec输出redirect到缓冲区或文件

我正在写一个C程序,我fork()exec()wait() 。 我想将我执行的程序的输出写入文件或缓冲区。

例如,如果我执行ls我想写file1 file2 etc缓冲区/文件。 我不认为有一种方法来读取标准输出,所以这意味着我必须使用pipe道? 这里有没有一个通用的程序,我没有find?

为了将输出发送到另一个文件(我将忽略错误检查以专注于重要的细节):

 if (fork() == 0) { // child int fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); dup2(fd, 1); // make stdout go to file dup2(fd, 2); // make stderr go to file - you may choose to not do this // or perhaps send stderr to another file close(fd); // fd no longer needed - the dup'ed handles are sufficient exec(...); } 

为了将输出发送到pipe道,您可以将输出读取到缓冲区中:

 int pipefd[2]; pipe(pipefd); if (fork() == 0) { close(pipefd[0]); // close reading end in the child dup2(pipefd[1], 1); // send stdout to the pipe dup2(pipefd[1], 2); // send stderr to the pipe close(pipefd[1]); // this descriptor is no longer needed exec(...); } else { // parent char buffer[1024]; close(pipefd[1]); // close the write end of the pipe in the parent while (read(pipefd[0], buffer, sizeof(buffer)) != 0) { } } 

你需要确定你想要做什么 – 最好更清楚地解释一下。

选项1:文件

如果你知道你要执行的命令的输出到哪个文件,那么:

  1. 确保父母和子女同意姓名(父母在分娩前决定姓名)。
  2. 父叉 – 你有两个过程。
  3. 子对文件进行重组,使文件描述符1(标准输出)进入文件。
  4. 通常,你可以单独留下标准错误。 你可能会从/ dev / nullredirect标准input。
  5. 孩子然后执行相关命令; 所述命令运行并且任何标准输出进入文件(这是基本的shell I / Oredirect)。
  6. 执行的过程然后终止。
  7. 同时,父母的过程可以采取两个主要策略之一:
    • 打开文件阅读,并继续阅读,直到它达到EOF。 然后需要仔细检查孩子是否死亡(这样就不会有更多的数据要读),或者等待更多的孩子input。
    • 等待孩子死亡,然后打开文件进行阅读。
    • 第一个好处是,当孩子也跑步时,家长可以做一些工作; 第二个好处就是你不需要用I / O系统(重复读取EOF)。

选项2:pipe道

如果您希望父级读取孩子的输出,请安排孩子将其输出回送给父级。

  1. 使用popen()来做这个简单的方法。 它将运行该进程并将输出发送到您的父进程。 请注意,由于pipe道具有较小的缓冲区大小(通常为4-5 KB),所以父级必须处于活动状态,并且如果子级生成的数据多于父级不读取时的数据,则子级将阻塞,直到父母阅读。 如果父母正在等待孩子死亡,则会陷入僵局。
  2. 使用pipe道()等难以做到这一点。 父母调用pipe道(),然后分叉。 孩子对pipe道进行分类,以便pipe道的写入结束是其标准输出,并确保与pipe道相关的所有其他文件描述符都closures。 这可能会使用dup2()系统调用。 然后执行所需的过程,将标准输出发送到pipe道。
  3. 同时,父母也closurespipe道的不需要的结束,然后开始阅读。 当它在pipe道上得到EOF时,它知道孩子已经完成并closures了pipe道; 它也可以closurespipe道的末端。

既然你看起来像在linux / cygwin环境中使用这个,你想使用popen 。 这就像打开一个文件,只有你会得到正在执行的程序stdout ,所以你可以使用正常的fscanffread

分叉之后,使用dup2(2)将文件的FD复制到stdout的FD中,然后执行exec。