Building a shell is a great exercise, but honestly having to deal with string parsing is such a bother that it robs like 2/3 of the joy along the way. I once built a very simple one in Go [0] as a learning exercise and I stopped once I started getting frustrated with all the corner cases.
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.
Fun read! I built a minimal Linux shell [0] in c and Zig last year which does not depend on libc. It was a great way to learn about execve, the new-ish clone3 syscall and how Linux starts a process. Parsing strings is the least fun part of the building the shell.
Had an assignment to build a shell in a week, how hard could it be?
controlling terminal
session leader
job control
The parser was easy in comparison.
ratzkewatzke
There's a very good exercise on Codecrafters (https://app.codecrafters.io/courses/shell/overview) to walk you through writing your own shell. I found it enlightening, as well as a good way to learn a new language.
lasgawe
Great article. There are many things every developer should do when starting to learn programming or when trying to improve their skills. This is one of them. I once built a shell-like programming language (not an interpreter). If anyone reading this wants to improve their skills, I strongly suggest building your own shell from scratch.
Unix shells are conceptually simple but hide a surprising amount of complexity under the hood that we take for granted. I recently had build my own PTY controller. There were so many edge-cases to deal with. It took weeks of stress testing and writing many tests to get it right.
doe88
Is there a (real) shell whose code is relatively short and self contained and would be valuable to read? This was always something I wanted to do but never quite spent time to look for a good one to explore.
show comments
zokier
Bit of pedantry but I don't think traditional unix shell (like this) follows repl model; the shell is not usually doing printing of the result of evaluation. Instead the printing happens more as a side effect of the commands.
show comments
dirk94018
Interesting. I wanted to do toast | bash to let the AI drive the computer but the bash shell really got in the way. Too much complexity. The things that annoy humans, $ expansion, special characters, etc don't work for AI either. Ended up writing a custom shell for AI (and humans). When a tool gets in the way, sometimes it just time to change the tool.
austy69
Fun read. Wonder if you are able to edit text in the shell, or if you need to implement a gap buffer to allow it?
Building a shell is a great exercise, but honestly having to deal with string parsing is such a bother that it robs like 2/3 of the joy along the way. I once built a very simple one in Go [0] as a learning exercise and I stopped once I started getting frustrated with all the corner cases.
[0] https://github.com/lourencovales/codecrafters/blob/master/sh...
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.
Some time ago I've written an article about a particular aspect of shells, job control: https://emersion.fr/blog/2019/job-control/
Fun read! I built a minimal Linux shell [0] in c and Zig last year which does not depend on libc. It was a great way to learn about execve, the new-ish clone3 syscall and how Linux starts a process. Parsing strings is the least fun part of the building the shell.
[0] https://gist.github.com/rrampage/5046b60ca2d040bcffb49ee38e8...
Had an assignment to build a shell in a week, how hard could it be?
The parser was easy in comparison.There's a very good exercise on Codecrafters (https://app.codecrafters.io/courses/shell/overview) to walk you through writing your own shell. I found it enlightening, as well as a good way to learn a new language.
Great article. There are many things every developer should do when starting to learn programming or when trying to improve their skills. This is one of them. I once built a shell-like programming language (not an interpreter). If anyone reading this wants to improve their skills, I strongly suggest building your own shell from scratch.
Link was previously posted by author: https://news.ycombinator.com/item?id=47398749 There are other good quality articles on their site, and maybe deserves the imaginary points.
Unix shells are conceptually simple but hide a surprising amount of complexity under the hood that we take for granted. I recently had build my own PTY controller. There were so many edge-cases to deal with. It took weeks of stress testing and writing many tests to get it right.
Is there a (real) shell whose code is relatively short and self contained and would be valuable to read? This was always something I wanted to do but never quite spent time to look for a good one to explore.
Bit of pedantry but I don't think traditional unix shell (like this) follows repl model; the shell is not usually doing printing of the result of evaluation. Instead the printing happens more as a side effect of the commands.
Interesting. I wanted to do toast | bash to let the AI drive the computer but the bash shell really got in the way. Too much complexity. The things that annoy humans, $ expansion, special characters, etc don't work for AI either. Ended up writing a custom shell for AI (and humans). When a tool gets in the way, sometimes it just time to change the tool.
Fun read. Wonder if you are able to edit text in the shell, or if you need to implement a gap buffer to allow it?