*nix Shell遇到管道符时是否调用pipe()函数?具体执行流程是什么?
Great questions—let's dive into how pipes work under the hood in *nix shells:
1. Does the *nix Shell call the pipe() system function when encountering a pipe (|)?
Absolutely yes. The pipe() system call is the foundational mechanism that enables inter-process communication (IPC) via pipes in *nix systems, so the shell relies on it directly whenever you use a | in a command line.
2. What specific operations does the *nix Shell perform, and does linking stdout of the previous command to stdin of the next involve pipe()?
Here's a step-by-step breakdown of what the shell does when processing a command like cmd1 | cmd2:
- First, the shell calls the
pipe()system function to create a unidirectional pipe. This returns two file descriptors: one for reading from the pipe (fd[0]) and one for writing to it (fd[1]). - Next, the shell uses
fork()to create a child process forcmd1:- In this child process, we don't need the pipe's read end, so we close
fd[0]. - We then redirect the child's standard output (stdout, which is file descriptor 1 by default) to the pipe's write end using
dup2(fd[1], 1). After this, anythingcmd1writes to stdout will go into the pipe. We can then close the originalfd[1]since it's no longer needed. - Finally, the child replaces its process image with
cmd1using anexec()family function (likeexecvp()).
- In this child process, we don't need the pipe's read end, so we close
- The shell then forks another child process for
cmd2:- In this child, we close the pipe's write end (
fd[1]) since we only need to read from the pipe. - We redirect the child's standard input (stdin, file descriptor 0) to the pipe's read end with
dup2(fd[0], 0). Nowcmd2will read input from the pipe instead of the default stdin (usually your terminal). We close the originalfd[0]afterward. - The child then replaces its process image with
cmd2viaexec().
- In this child, we close the pipe's write end (
- Back in the parent shell process, we close both ends of the pipe (
fd[0]andfd[1])—the shell doesn't need to read or write to the pipe itself. - Finally, the shell waits for both child processes to finish executing using
wait()orwaitpid().
To directly answer the second part of your question: Yes, linking the previous command's stdout to the next command's stdin entirely relies on the pipe() system call. The pipe acts as the buffer between the two processes, and the dup2() calls connect each command's standard streams to the pipe's ends.
内容的提问来源于stack exchange,提问作者George Robinson

