How does Shell implement a channel programmatically?

I understand how I / O redirection works on Unix / Linux, and I know that Shell uses this function for pipelined programs with a special file type - anonymous pipe. But I would like to know more about how Shell implements it programmatically? I'm interested in not only the involved system calls, but the whole picture.

For example, ls | sorthow does Shell perform an I / O redirection for lsand sort?

+3
source share
2 answers

The whole picture is complex, and the best way to understand is to study a small shell. For a limited picture here. Before doing anything, the shell analyzes the entire command line to know exactly how the process chain is. Let them say that he meets proc1 | proc2.

  • He sets up the phone. In short, the entry in thepipe[0]ends onthepipe[1]

    int thepipe[2];
    pipe(thepipe);
    
  • He deploys the first process and changes the direction of his stdout to exec

    dup2 (thepipe[1], STDOUT_FILENO);
    
  • He launches a new program that blissfully does not know about redirects and simply writes it into stdouthow well the process is.

  • He deploys the second process and changes the source of his stdin before exec

    dup2 (thepipe[0], STDIN_FILENO);
    
  • He launches a new program that does not know that its input comes from another program.

, . daisy- , , .

+3

silberschatz

, fork() ... , ! ( , !)

, ( fork() ..) , , ,

ls | sort

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

    #define BUFFER SIZE 25
    #define READ END 0
    #define WRITE END 1
    int main(void)
    {
    char write msg[BUFFER SIZE] = "Greetings";
    char read msg[BUFFER SIZE];
    int fd[2];
    pid t pid;

    /* create the pipe */
    if (pipe(fd) == -1) {
    fprintf(stderr,"Pipe failed");
    return 1;
    }
    /* fork a child process */
    pid = fork();
    if (pid < 0) { /* error occurred */
    fprintf(stderr, "Fork Failed");
    return 1;
    }
    if (pid > 0) { /* parent process */
    /* close the unused end of the pipe */
    close(fd[READ END]);
    /* write to the pipe */
    write(fd[WRITE END], write msg, strlen(write msg)+1);
    /* close the write end of the pipe */
    close(fd[WRITE END]);
    }
    else { /* child process */
    /* close the unused end of the pipe */
    close(fd[WRITE END]);
    /* read from the pipe */
    read(fd[READ END], read msg, BUFFER SIZE);
    printf("read %s",read msg);
    }
    }
    /* close the write end of the pipe */
    close(fd[READ END]);
    return 0;
    }
+1

All Articles