输入重定向和管道

时间:2016-01-24 08:50:13

标签: c redirect pipe execvp

我理解你想要运行像ls -l |这样的命令的管道wc -l:

int pipes[2];
pipe(pipes); 

if (fork() == 0){ //first fork
  dup2(pipes[1],1); 
  close(pipes[0]);
  close(pipes[1]);

  execvp(arr1[0], arr1); //arr1[0] = "ls" and  arr1[1] = "-l" and arr1[2] = 0
  perror("Ex failed");
  exit(1);
}

if (fork() == 0){ //2nd fork
  close(pipes[1]);
  dup2(pipes[0],0); 
  close(pipes[0]);

  execvp(arr2[0], arr2); //arr2[0] = "wc" and  arr2[1] = "-l" and arr2[2] = 0
  perror("Ex failed");
  exit(1);
}

但是,您将如何包含输入和输出重定向?让我说我想要猫&lt; foo.txt | wc -l <​​/ p>

我理解第一个分叉需要修改,但我不了解需要什么(另一个dup2()?)。我非常感谢一些帮助。

感谢。

1 个答案:

答案 0 :(得分:0)

  

但是,您将如何包含输入和输出重定向?我想说吧   想要猫&lt; foo.txt | wc -l <​​/ p>

在输入重定向的情况下,打开文件进行读取,然后使用dup2(2)将文件描述符复制到标准输入中。 stdin的文件描述符为STDIN_FILENO,在unistd.h中定义。所以,像这样:

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

// ...

filename = "foo.txt";
int fd;
if ((fd = open(filename, O_RDONLY)) == -1) {
    perror("open %s: %s\n", filename, strerror(errno));
    exit(EXIT_FAILURE);
}
if (dup2(fd, STDIN_FILENO) == -1) {
    perror("dup2: %s -> stdin: %s\n", filename, strerror(errno));
    exit(EXIT_FAILURE);
}
if (close(fd) == -1) {
    perror("close %s: %s\n", filename, strerror(errno));
    exit(EXIT_FAILURE);
}

// Now, reading from stdin will read from the file.
// Do the normal pipe operations here.

int pipes[2];
// ...

请注意,您的代码没有错误处理 - 不是一个 - 这非常糟糕,因为当出现问题时,您将忽略它并且代码将以神秘的方式崩溃。几乎你调用的每个函数都会返回错误;考虑处理错误,以清楚地向用户显示出错的地方。