You are not passing the current shell state though. So you could start 3 new shell processes with enough data to set the state right and then start the individual processes but that is both inelegant and inefficient.
Instead if we fork thrice and each fork execs a command and does the pipeline plumbing, all three processes start simultaneously and inherit the exact same shell state all for free. And copy on write means we did not waste any memory replicating the shell state for 3 processes.
Pipe pipe1 = new Pipe() Pipe pipe2 = new Pipe() NewProcess("cmd_a", null, pipe1) NewProcess("cmd_b", pipe1, pipe2) NewProcess("cmd_c", pipe2, null)