Honestly this was one of the most influential pieces of writing I've ever read. Back in the day this opened up a lot of the implementation details on interpreters and C for me. It quite literally helped "get" how programs are designed and written.
I found this piece around eighth grade and I'm very glad I did! :-)
I saw a similar small shell in C as a tutorial but it was from a book made in the 1980s on unix programming. Been wondering what that book was ever since because it was just something sitting around at a job that I didn't get to read all the way through, but it really made things click finally
Writing a shell in C is in some ways easier than writing a shell in a higher language.
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.
Related. Others?
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)
I wrote a shell in C for Bruce Molay's Unix System Programming class. I thought the hardest part was getting the globbing, special characters, and escaping to work right. The other element of Unix system programming in C (that some may not be aware of) is that you are expected to make sure every line is 80 char or less. At the end of the day, I was proud of what I accomplished, but I think I only got a _C_ on the assignment.
This was one of my favorite exercises in my introductory C classes in college. I'm gratified to see other people with warm and enlightened reactions to implementing something like this; it was a monumental and eye-opening assignment for me and I couldn't help but tinker with it for weeks. Many others saw it as just a box ticking exercise with annoying string and OS munging, but it felt like I had a secret of the universe laid bare for me in seeing how to go from toy C programs to a useful shell that accelerated some special purpose tasks.
Can you elaborate on 'useful shell that accelerated some special purpose tasks'? I'm curious about the types of things that people have done with their own shells.
You might have a look the source for Advanced UNIX Programming by Marc Rochkind, too.
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.
I would like to recommend "Understanding UNIX/LINUX Programming: A Guide to Theory and Practice" for beginners.
You can download source code I assembled https://github.com/bssrdf/UnderstandingUnixLinuxProgramming
This so reminds me of the command line I've added to a little fun tool I wrote in Borland C ~25 years ago. It was a strobe light using your monitor and I wanted something to fine tune the timings and color so I sat down a whole afternoon and added a command line interface including line editing and history. So much fun!
I wrote a toy shell last summer and this was one of the pieces I referred to most.
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.
Very nice especially the pedagogy. A little bit of code (in a top-down manner) together with the corresponding explanation for a complete app is how things used to be explained in the old days. I still remember studying Al Stevens' book Turbo C: Memory Resident Utilities, Screen I-O and Programming Techniques (for DOS) and learning how to layer software viz. 1) a layer over BIOS, 2) a layer to draw windows using (1) 3) a desktop manager using (2) 4) a text editor 5) making the editor memory-resident. Reading that book really taught me how to use C to build a non-trivial app.
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.
For people who are interested in this stuff, I really recommend just getting a copy of Advanced Programming in the UNIX Environment and flipping through all (or most) of it. Pretty de-mystifying (and a good argument for caring about what OS you use!).
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.
The glibc manual has a section about writing a job control shell: https://www.gnu.org/software/libc/manual/html_mono/libc.html...
[flagged]