Comment by wei03288
8 hours ago
The pipe section is the part that changes how you think about processes. Once you've manually done the dup2 dance — close write-end in parent, close read-end in child, wire them up — it stops being magic and starts being obvious why `grep | sort | uniq` works at all. The thing that surprised me building a similar toy was how late in the process job control has to come: you can get a working pipe chain surprisingly fast, and then job control (SIGTSTP, tcsetpgrp, the whole mess) costs 5x more than everything else combined.
Yup, job control is a huge mess. I think Bill Joy was able to modify the shell, the syscall interface, and the terminal driver at the same time to implement the hacky mechanism of job control. But a few years later that kind of crosscutting change would have been harder
One thing we learned from implementing job control in https://oils.pub is that the differing pipeline semantics of bash and zsh makes a difference
In bash, the last part of the pipeline is forked (unless shopt -s lastpipe)
In zsh, it isn't
And then that affects this case:
So yeah the semantics of shell are not very well specified (which is one reason for OSH and YSH). I recall a bug running an Alpine Linux shell script where this difference matters -- if the last part is NOT forked, then the script doesn't run
I think there was almost a "double bug" -- the script relied on the `read` output being "lost", even though that was likely not the intended behavior
Yes!! This!! I wrote a shell awhile back and was pretty happy with it... but could _not_ get job control to work quite right. It was a big pain.