将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(标准输出)进入文件。
- 通常,你可以单独留下标准错误。 你可能会从/ dev / nullredirect标准input。
- 孩子然后执行相关命令; 所述命令运行并且任何标准输出进入文件(这是基本的shell I / Oredirect)。
- 执行的过程然后终止。
- 同时,父母的过程可以采取两个主要策略之一:
- 打开文件阅读,并继续阅读,直到它达到EOF。 然后需要仔细检查孩子是否死亡(这样就不会有更多的数据要读),或者等待更多的孩子input。
- 等待孩子死亡,然后打开文件进行阅读。
- 第一个好处是,当孩子也跑步时,家长可以做一些工作; 第二个好处就是你不需要用I / O系统(重复读取EOF)。
选项2:pipe道
如果您希望父级读取孩子的输出,请安排孩子将其输出回送给父级。
- 使用popen()来做这个简单的方法。 它将运行该进程并将输出发送到您的父进程。 请注意,由于pipe道具有较小的缓冲区大小(通常为4-5 KB),所以父级必须处于活动状态,并且如果子级生成的数据多于父级不读取时的数据,则子级将阻塞,直到父母阅读。 如果父母正在等待孩子死亡,则会陷入僵局。
- 使用pipe道()等难以做到这一点。 父母调用pipe道(),然后分叉。 孩子对pipe道进行分类,以便pipe道的写入结束是其标准输出,并确保与pipe道相关的所有其他文件描述符都closures。 这可能会使用dup2()系统调用。 然后执行所需的过程,将标准输出发送到pipe道。
- 同时,父母也closurespipe道的不需要的结束,然后开始阅读。 当它在pipe道上得到EOF时,它知道孩子已经完成并closures了pipe道; 它也可以closurespipe道的末端。
既然你看起来像在linux / cygwin环境中使用这个,你想使用popen 。 这就像打开一个文件,只有你会得到正在执行的程序stdout
,所以你可以使用正常的fscanf
, fread
等
分叉之后,使用dup2(2)
将文件的FD复制到stdout的FD中,然后执行exec。