3 回答
TA贡献1826条经验 获得超6个赞
为了将输出发送到另一个文件(我省去了错误检查,将重点放在重要的细节上):
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(...);
}
要将输出发送到管道,以便随后将输出读入缓冲区:
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)
{
}
}
TA贡献1856条经验 获得超11个赞
您需要准确地决定要做什么-最好对其进行更清晰的说明。
选项1:文件
如果知道要将执行的命令的输出转到哪个文件,则:
确保父母和孩子在姓名上达成一致(父母在分叉之前确定姓名)。
父叉-您有两个过程。
子级重新组织事物,以便文件描述符1(标准输出)进入文件。
通常,您可以不理会标准错误;您可以从/ dev / null重定向标准输入。
然后孩子执行相关命令;该命令运行,所有标准输出到达文件(这是基本的Shell I / O重定向)。
然后执行的过程终止。
同时,父流程可以采用以下两种主要策略之一:
打开文件进行读取,并继续读取直到到达EOF。然后,它需要仔细检查孩子是否死亡(因此不再需要读取任何数据),或者闲逛以等待孩子的更多输入。
等待孩子死亡,然后打开文件进行阅读。
第一个优点是父母可以在孩子还奔跑的同时做一些工作。第二个优点是您不必迷惑I / O系统(重复读取过去的EOF)。
选项2:管道
如果希望父级从子级读取输出,请安排子级将其输出通过管道返回给父级。
使用popen()可以很容易地做到这一点。它将运行该进程并将输出发送到您的父进程。请注意,在子级生成输出时,父级必须处于活动状态,因为管道的缓冲区大小较小(通常为4-5 KB),并且如果子级生成的数据多于父级不读取时的数据,则子级将阻塞直到父母读。如果父母正在等待孩子的死亡,那么您将陷入僵局。
使用pipe()等很难做到这一点。父级调用pipe(),然后进行派生。子进程对管道进行分类,以使管道的写端成为其标准输出,并确保关闭与管道有关的所有其他文件描述符。这很可能使用dup2()系统调用。然后,它执行所需的过程,该过程将其标准输出发送到管道。
同时,父级还会关闭管道的多余末端,然后开始阅读。当它在管道上发生EOF时,它知道孩子已经完成并关闭了管道。它也可以关闭管道的末端。
- 3 回答
- 0 关注
- 758 浏览
添加回答
举报