I've been reading up about how pipes are implemented in the Linux kernel and wanted to validate my understanding. If I'm incorrect, the answer with the correct explanation will be selected.
- Linux has a VFS called pipefs that is mounted in the kernel (not in user space)
- pipefs has a single super block and is mounted at it's own root (
pipe:), alongside/ - pipefs cannot be viewed directly unlike most file systems
- The entry to pipefs is via the
pipe(2)syscall - The
pipe(2)syscall used by shells for piping with the|operator (or manually from any other process) creates a new file in pipefs which behaves pretty much like a normal file - The file on the left hand side of the pipe operator has its
stdoutredirected to the temporary file created in pipefs - The file on the right hand side of the pipe operator has its
stdinset to the file on pipefs - pipefs is stored in memory and through some kernel magic, shouldn't be paged
Is this explanation of how pipes (e.g. ls -la | less) function pretty much correct?
One thing I don't understand is how something like bash would set a process' stdin or stdout to the file descriptor returned by pipe(2). I haven't been able to find anything about that yet.
pipe()kernel call along with the machinery that supports it (pipefs, etc) is much lower level than the|operator offered in your shell. The latter is usually implemented using the former, but it doesn't have to be.|operator is just callingpipe(2)as a process like bash does.