Write a Shell in C (2015)
brennan.io
brennan.io
I found this piece around eighth grade and I'm very glad I did! :-)
A very good Unix book with lots of projects like shell, token ring etc. is Practical UNIX Programming: A Guide to Concurrency, Communication, and Multithreading by Kay Robbins and Steven Robbins. It's 2nd edition is named UNIX Systems Programming: Communication, Concurrency and Threads. The code given in the book is really illuminating.
Write a Shell in C - https://news.ycombinator.com/item?id=26126010 - Feb 2021 (80 comments)
Write a Shell in C (2015) - https://news.ycombinator.com/item?id=13112589 - Dec 2016 (68 comments)
Write a Shell in C - https://news.ycombinator.com/item?id=8907392 - Jan 2015 (8 comments)
We just ported fish from C/C++ to rust and the amount of semantically unsafe operations a shell does (eg passing around file descriptors instead of a File object that can only have a single mutable reference unless you want to place it in a lock) and the onerous requirements of OS internals that require the use of only async-safe methods in signal handlers and post-fork/pre-exec (which is hard/impossible to do correctly if you’re using high-level wrappers) are quite something.
C is probably the ideal language for a basic shell, which should come as no surprise as OS and libc functionality to make that happen was co-developed.
In the book it starts literally with a one-shot shell - exec - and moves onto fancier ones, including piping etc.
First version of source accompanying the book is at https://github.com/gmarler/AUPv2/blob/master/c5/sh0.c and does multiple commands.
Writing the beginnings of a shell is surprisingly easy. fork() and exec() do all the heavy lifting. I would recommend it as a great systems programming exercise.
What stands out in reading the 1.0 remarks is that the person writing it clearly cared about shells as an everyday user of them.
You can download source code I assembled https://github.com/bssrdf/UnderstandingUnixLinuxProgramming
Then you can pick up some book on shells (Effective Linux at the Command Line is one I'm going through right now), and you can piece a lot of it together.
There's no magic, just a combo of decent ideas working together. But no single idea is hard to implement. Maybe just hard to come up with from scratch.