【问题标题】:Writing to file descriptor写入文件描述符
【发布时间】:2011-05-11 10:22:42
【问题描述】:

在下面的 sn-p 中,我将 ls 命令的输出重定向到 wc -l 的输入,这非常有效。现在我还想将 ls 命令的输出重定向到一个名为“beejoutput.xml”的文件。 txt" 使用以下代码,但它不起作用。需要帮助。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
  int pfds[2];
  pipe(pfds);
  if (!fork())
  {
    dup2(pfds[1],1);
    close(pfds[0]); 
    execlp("ls", "ls",NULL);
  }
  else
  {
    FILE *outputO=fopen ("beejoutput.txt", "w"); //opening file for writing

    dup2(pfds[0],0);
    dup2(fileno(outputO),pfds[0]); 
    close(pfds[1]); 
    execlp("wc", "wc","-l", NULL);
  }

  return 0;
}

【问题讨论】:

  • 为什么要在 execlp("wc") 之前关闭 pfds[1]?
  • 因为 FD 不应该传递给 wc 命令。
  • @weekens:因为我们不想向管道写入任何内容。pfds[1] 将用于从父进程向子进程发送数据。
  • 好的。您能否在 fopen 之后评论 2 次对 dup2 的调用? (我读了那个人,但还是听不懂。)编辑:尤其是第一个。

标签: c process file-descriptor child-process dup2


【解决方案1】:

dup 函数复制了一个文件描述符,也就是说,之后新旧文件描述符都引用同一个打开的文件。这不同于让一个文件描述符同时引用两个不同的文件。

如果你想将相同的数据发送到两个不同的目的地,你需要在不同的进程中生成两个命令,然后自己进行复制,或者生成“tee”命令的副本——无论哪种方式,你最终都会三个进程。

【讨论】:

  • 如果我只想将数据发送到文件而不是wc -l 怎么办。我无法将数据单独发送到文件
  • @Simon:不起作用..用dup2(fileno(outputO), 0);替换dup2(pfds[0], 0);
  • @scholar:将dup2(fileno(outputO),pfds[0]);替换为dup2(fileno(output0),1)
  • @John:这会将wc -l 的输出发送到文件。但我想将ls 的输出发送到文件
  • 尝试在strace 中运行您的程序,这应该可以让您很好地了解它的实际功能。
【解决方案2】:

这对我有用:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main(void)
{
    int pfds[2];
    pipe(pfds);

    pid_t childpid = fork();

    if (childpid == 0) {
        /* Child */
        dup2(pfds[1],1);
        close(pfds[0]); 

        execlp("ls", "ls",NULL);

    } else {
        /* Parent */

        pid_t retpid;
        int  child_stat;
        while ((retpid = waitpid(childpid, &child_stat, 0)) != childpid && retpid != (pid_t) -1)
            ;

        close(pfds[1]); 

        char buf[100];
        ssize_t bytesread;

        int fd = open("beejoutput.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
        if (fd == -1) {
            fprintf(stderr, "Opening of beejoutput.txt failed!\n");
            exit(1);
        }

        /* This part writes to beejoutput.txt */
        while ((bytesread = read(pfds[0], buf, 100)) > 0) {
            write(fd, buf, bytesread);
        }

        lseek(fd, (off_t) 0, SEEK_SET);
        dup2(fd, 0);
        execlp("wc", "wc", "-l", NULL);
    }

    return 0;
}

【讨论】:

    【解决方案3】:

    尝试检查您执行的所有系统调用的结果代码(包括 dup2)。这可能会引导您找到答案。无论如何,这是一个好习惯。

    【讨论】:

      猜你喜欢
      • 2019-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 2010-09-20
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多