【问题标题】:Need to implement a pipe, dup2 function to perform "ls | tr a-z A-Z > file.txt"需要实现一个管道,dup2函数来执行“ls | tr a-z A-Z > file.txt”
【发布时间】:2013-12-05 13:34:56
【问题描述】:

我有以下 C 代码,它执行“ls | tr a-z A-Z”,但我不知道如何使输出转到 file.txt。我需要三次创建另一个管道或叉子吗?由于我将输出保存到文件中,是否需要使用 open() 函数?

int main() {
pid_t child_pid_one, child_pid_two;
int pipe_fd[2]; /* pipe */

/* Before the fork, we need to create the pipe */ 
/* (otherwise no sharing of pipe) */
if (pipe(pipe_fd) < 0) {
  err(EX_OSERR, "pipe error");
}

if ((child_pid_one = fork()) < 0) {
  err(EX_OSERR, "fork error");
}

if (child_pid_one == 0)  { /* CHILD #1's code (ls code) */
  close(pipe_fd[0]); /* we don't need pipe's read end */

  /* Redirecting standard output to pipe write end */
  if (dup2(pipe_fd[1], STDOUT_FILENO) < 0) {
     err(EX_OSERR, "dup2 error");
  }

  execlp("/bin/ls", "/bin/ls", NULL);
  err(EX_OSERR, "exec error");
}  else { /* parent's code */

  /* Creating second child */
  if ((child_pid_two = fork()) < 0) {
     err(EX_OSERR, "fork error");
  } 

  if (child_pid_two == 0)  { /* CHILD #2's code (tr a-z A-Z) */
     close(pipe_fd[1]); /* we don't need pipe's write end */

     /* Redirecting standard input to pipe read end */
     if (dup2(pipe_fd[0], STDIN_FILENO) < 0) {
        err(EX_OSERR, "dup2 error");
     }


     execlp("/usr/bin/tr", "/usr/bin/tr","a-z","A-Z", NULL);
     err(EX_OSERR, "exec error");
  } else {
     /* Parent has no need for the pipe */
     close(pipe_fd[0]);
     close(pipe_fd[1]);

     /* Reaping each children */
     wait(NULL); 
     wait(NULL);
  }
 }

 return 0;
}

【问题讨论】:

    标签: c pipe dup2


    【解决方案1】:

    只需将tr 进程的STDOUT_FILENO 重定向到新打开的文件:

    // write-only (as is stdout), truncate to zero length
    int file_fd = open("file.txt", O_WRONLY | O_TRUNC);
    
    if (file_fd < 0) {
        // error handling
    }
    
    if (dup2(file_fd, STDOUT_FILENO) < 0) {
        err(EX_OSERR, "dup2 error");
    }
    

    【讨论】:

    • 你太棒了!谢谢你。假设我要进行 EngToIta 翻译。我对 EngToFre 使用上面相同的代码,它相当于“EngToSpa | SpaToFre”,但我想为 EngToIta 执行“EngToSpa | SpaToFre | FreToIta”。我将如何处理这个问题?
    • @user3022651:如果你想在管道上有三个进程,你必须创建 2 对管道(通过父级中的两个单独的 pipe 调用),然后 fork 两次.
    猜你喜欢
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    • 2016-02-26
    相关资源
    最近更新 更多