u/Full_Plane

Built a custom Mini-Shell in Go: Exploring process management and background jobs

Built a custom Mini-Shell in Go: Exploring process management and background jobs

Hello r/sideprojects

I have been exploring systems programming and recently built a custom shell entirely in Go to understand how process management works under the hood. I wanted to share my experience and get some feedback on the implementation.

While the basic loop of a shell (read, parse, execute) is simple, managing background processes and file descriptors introduced some interesting challenges.

Here is a breakdown of what I implemented and the technical hurdles:

  • Process Management: Getting background jobs to run without hanging the main terminal was a challenge. I had to ensure proper redirection to os.DevNull so background processes could detach correctly.
  • File Descriptors and Concurrency: I ran into bugs related to file descriptor leaks and concurrent execution when handling complex commands. Designing a modular architecture helped isolate these issues.
  • Signal Handling: Implementing custom signal handling (like catching SIGINT in the parent shell while allowing foreground children to exit) was necessary to prevent the shell from closing unexpectedly.
  • Environment: The project includes a multi-stage Dockerfile for a reproducible setup.
  • Run using Docker: docker run -it kunaldev1oper/mini-shell:latest

You can find the source code and architecture documentation here: https://github.com/Kunal-deve1oper/mini-shell

A quick terminal recording of it in action is here: https://asciinema.org/a/1145072

I would appreciate any code reviews, suggestions on idiomatic Go usage, or feedback on how the process management could be improved.

u/Full_Plane — 14 days ago