为了账号安全,请及时绑定邮箱和手机立即绑定

将exec输出重定向到缓冲区或文件

将exec输出重定向到缓冲区或文件

C
慕田峪7331174 2019-10-25 15:38:28
我正在写一个C程序中我fork(),exec()和wait()。我想将执行的程序的输出写入文件或缓冲区。例如,如果我执行,ls 我想写入file1 file2 etc缓冲区/文件。我认为没有办法读取stdout,这是否意味着我必须使用管道?这里有我找不到的一般程序吗?
查看完整描述

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)

    {

    }

}


查看完整回答
反对 回复 2019-10-25
?
呼唤远方

TA贡献1856条经验 获得超11个赞

您需要准确地决定要做什么-最好对其进行更清晰的说明。

选项1:文件

如果知道要将执行的命令的输出转到哪个文件,则:

  1. 确保父母和孩子在姓名上达成一致(父母在分叉之前确定姓名)。

  2. 父叉-您有两个过程。

  3. 子级重新组织事物,以便文件描述符1(标准输出)进入文件。

  4. 通常,您可以不理会标准错误;您可以从/ dev / null重定向标准输入。

  5. 然后孩子执行相关命令;该命令运行,所有标准输出到达文件(这是基本的Shell I / O重定向)。

  6. 然后执行的过程终止。

  7. 同时,父流程可以采用以下两种主要策略之一:

    • 打开文件进行读取,并继续读取直到到达EOF。然后,它需要仔细检查孩子是否死亡(因此不再需要读取任何数据),或者闲逛以等待孩子的更多输入。

    • 等待孩子死亡,然后打开文件进行阅读。

    • 第一个优点是父母可以在孩子还奔跑的同时做一些工作。第二个优点是您不必迷惑I / O系统(重复读取过去的EOF)。

选项2:管道

如果希望父级从子级读取输出,请安排子级将其输出通过管道返回给父级。

  1. 使用popen()可以很容易地做到这一点。它将运行该进程并将输出发送到您的父进程。请注意,在子级生成输出时,父级必须处于活动状态,因为管道的缓冲区大小较小(通常为4-5 KB),并且如果子级生成的数据多于父级不读取时的数据,则子级将阻塞直到父母读。如果父母正在等待孩子的死亡,那么您将陷入僵局。

  2. 使用pipe()等很难做到这一点。父级调用pipe(),然后进行派生。子进程对管道进行分类,以使管道的写端成为其标准输出,并确保关闭与管道有关的所有其他文件描述符。这很可能使用dup2()系统调用。然后,它执行所需的过程,该过程将其标准输出发送到管道。

  3. 同时,父级还会关闭管道的多余末端,然后开始阅读。当它在管道上发生EOF时,它知道孩子已经完成并关闭了管道。它也可以关闭管道的末端。


查看完整回答
反对 回复 2019-10-25
  • 3 回答
  • 0 关注
  • 758 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信