20

How do I use dup2 to perform the following command?

ls -al | grep alpha | more
Rob Kearnes
  • 201
  • 1
  • 2
  • 3

2 Answers2

32

A Little example with the first two commands. You need to create a pipe with the pipe() function that will go between ls and grep and other pipe between grep and more. What dup2 does is copy a file descriptor into another. Pipe works by connecting the input in fd[0] to the output of fd[1]. You should read the man pages of pipe and dup2. I may try and simplify the example later if you have some other doubts.

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define READ_END 0
#define WRITE_END 1

int 
main(int argc, char* argv[]) 
{
    pid_t pid;
    int fd[2];

    pipe(fd);
    pid = fork();

    if(pid==0)
    {
        printf("i'm the child used for ls \n");
        dup2(fd[WRITE_END], STDOUT_FILENO);
        close(fd[WRITE_END]);
        execlp("ls", "ls", "-al", NULL);
    }
    else
    { 
        pid=fork();

        if(pid==0)
        {
            printf("i'm in the second child, which will be used to run grep\n");
            dup2(fd[READ_END], STDIN_FILENO);
            close(fd[READ_END]);
            execlp("grep", "grep", "alpha",NULL);
        }
    }

    return 0;
}
inspector-g
  • 4,146
  • 2
  • 24
  • 33
theprole
  • 2,274
  • 23
  • 25
  • it could be improved by using only one fork() and using the original process for either ls or grep, but well I'll leave that to you :P – theprole Sep 04 '10 at 17:40
  • How should we pipe the output of the grep to the more. It is just piping two processes right ? – CanCeylan Feb 12 '12 at 23:03
  • 2
    Shouldn't you close the WRITE_END for grep and the READ_END for ls (opposite of what you did)? – emem May 10 '15 at 11:45
  • not working when first `execlp()` changed with `execlp("cat", "cat", "test.c", NULL);` and next with `execlp("tail", "tail", "-n", "3",NULL);` – Ilaya Raja S Jan 23 '17 at 17:17
  • 2
    Example is majorly flawed. You didn't check if the fork failed, and you should always close both ends of the pipe, not just one. Otherwise, the parent attempting to read until EOF will never receive EOF. –  Oct 23 '17 at 21:00
2

You would use pipe(2,3p) as well. Create the pipe, fork, duplicate the appropriate end of the pipe onto FD 0 or FD 1 of the child, then exec.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358