Methods
42 (IX): minishell, a terminal from scratch
Recreating bash: parser, pipes, redirections, environment variables. The project
2 min read
After the threads at the table in 42 (VIII): philosophers, the project that earns the most respect at 42, without discussion: recreating a shell, the command interpreter that makes the terminal understand what you type. When you finish, every time you chain commands you look at the screen with different eyes. This is the story of my minishell, which ended up having its own personality: MSX BASIC style.
What the project asked for
Recreate a part of bash in C: a prompt that reads commands, a parser (the translator that converts text into something executable), an executor that launches external binaries (programs that live outside the shell) and its own builtins (commands that live inside: cd, echo, export, unset, env, pwd, exit), pipes (connecting the output of one command with the input of the next), redirections, environment variables, and handling signals (system messages, like Ctrl+C) properly. No banners or frills: if parsing fails, the shell must never die.
The architecture I used
I separated the project into clear layers: parser, executor, builtins, environment, main loop, and signals, each thing with its own module. When the path between input and command execution passes through so many hands, knowing where each thing lives is the difference between moving forward and going crazy. The final repo has the full documentation per module, and I still use it as a reference.
The three obstacles I remember
Quotes and expansion. The parser swallowed everything fine until someone typed echo "" "" and a command lost along the way disappeared. It took me a whole debugging session to understand that empty expansion is its own case, not an exception.
Ctrl+C. Having the shell ignore the interrupt while child processes (the programs it launches) receive it is a dance of signals I had to rewrite more than once. The "fix ctrl+c" commit is one of the ones that gave me the most satisfaction.
The "still reachable". Valgrind (the tool that hunts memory leaks) came out clean but with a little tail: memory still reachable. Technically no one forces you to free it, but I opened a specific branch to leave the trace completely clean. It was almost therapeutic work: closing every door through which anything could escape.
The detail that makes it mine
The presentation with the clean environment coincided with a personal way of doing things: the prompt and messages following MSX BASIC style, the computer on which I started. The repository is called minishell_msx for a reason: there's a small tribute inside.
It was over a hundred commits, weeks of testing, and a few long nights. But since then, when I type ls | grep x > output.txt, I know exactly what happens underneath. And that's never forgotten. The school's next challenge was painting in 3D: 42 (X): Cub3D.