This is the first post in a series where I plan to document my experience writing a small Unix shell in Rust called wishr. In this post, I’ll describe why I’m starting this project and how I plan to proceed through it.
Why write a shell? Link to heading
First off, to be clear, I have no intention to make a production quality shell: Bash, Z Shell, fish, and the like, can all breathe a sigh of relief here! 😄 This is a learning experience for me, and I want to document the process so that maybe it’ll be a learning experience for others too!
I’ve recently been studying Operating Systems, using a handful of books and online courses. It seems like writing a shell is a bit of a rite of passage, as pretty much all of the resources I’ve looked at include this as a lab exercise. And, this is for good reason! A shell is a tool that many programmers are very familiar with, and it is great for getting familiar with processes, system calls, and signal handling, but without the added complexity of a graphical interface. For all of these reasons, I’ve wanted to write a small shell to solidify some of the ideas I’ve been learning about.
Another reason that creating a shell is a common early lab exercise is, I think, to get students familiar with writing C code, which is the standard for Operating Systems, particularly OS’s based on Unix. I am far from an expert in C, but I can make my way through reading it, and I’ve done at least some small projects using C in the past. I’ve also worked professionally with languages descended from C, and, so, even though there are times I need to Google some odd syntax when I read C, for the most part I can follow along. But, there is a systems language that I have not used much at all that I would like to play around with: Rust.
Where does “wishr” come from? Link to heading
One of the primary resources I’ve been using to study Operating Systems is Operating Systems: Three Easy Pieces (aka, “OSTEP”). OSTEP was written primarily by professors at the University of Wisconsin-Madison. OSTEP is used in OS courses at Wisconsin (and many other universities!), and the authors have kindly shared some ideas for projects that they have used alongside OSTEP in OS courses they have taught. These projects, along with an automated tester for the projects, can be found on GitHub. One of these projects is wish (the “Wisconsin Shell”), a small Unix shell project.
Because the tests check input and output and are not language specific, it seemed like a good opportunity to leverage the tests that the OSTEP authors have kindly made available, even though I’d like to write my shell in Rust. So, “wishr” is essentially “wish” but with a small nod to the fact that it is written in Rust.
How will this series / project go? Link to heading
Well, that’s a good question! I haven’t written a shell before, I’m new to Rust, and, also, this blog is new as well. So, there are a lot of moving parts, and I’d be lying if I said I know how this will go! It’s possible this will be my first and last post. 😅
With that said, what I plan to do is to chip away at the overall project until I get to a point where all of the automated tests referenced above will pass on wishr. When facing a somewhat sizable software project like this, I like to use the Mikado Method as a way make incremental progress without getting overwhelmed, as well as avoiding huge merges. The method shines when working on existing code, but I have had some success with it even for new development. So, I’ll start by using some of the early automated tests as “goals” and then use Mikado to work back from there, iterating and moving on to new tests until, eventually, we get to a full set of passing tests! Fingers crossed! 🤞
I’m looking forward to getting started!