https://github.com/tigran-sargsyan-w/minishell
This project is about creating a simple shell. Yes, your own little bash. You will learn a lot about processes and file descriptors.
https://github.com/tigran-sargsyan-w/minishell
42 42school c c-language cli executor execve fork lexer mandatory minishell parser posix readline shell signals terminal unix unix-shell
Last synced: about 2 months ago
JSON representation
This project is about creating a simple shell. Yes, your own little bash. You will learn a lot about processes and file descriptors.
- Host: GitHub
- URL: https://github.com/tigran-sargsyan-w/minishell
- Owner: tigran-sargsyan-w
- Created: 2025-04-23T09:40:57.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-06-20T09:49:03.000Z (12 months ago)
- Last Synced: 2025-06-27T15:51:15.233Z (12 months ago)
- Topics: 42, 42school, c, c-language, cli, executor, execve, fork, lexer, mandatory, minishell, parser, posix, readline, shell, signals, terminal, unix, unix-shell
- Language: C
- Homepage:
- Size: 418 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Minishell πβ¨
β
**Completed**: Mandatory (101/100)

**Minishell** is a tiny Unix shell written in C for the 42 School curriculum.
It reproduces an essential subset of *bash* behaviour β command parsing, environment-variable expansion, redirections, pipelines, built-ins and proper signal handling β all without forking off to an external parser. The goal is to give you hands-on experience with lexical analysis, recursive-descent parsing, process control (`fork` / `execve` / `waitpid`), file-descriptor juggling and the subtleties of POSIX signals.

---
## π Table of Contents
- [Description](#description)
- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
- [How It Works](#how-it-works)
- [Tests](#tests)
- [Troubleshooting](#troubleshooting)
---
## π Description
`minishell` launches an interactive prompt that lets you execute commands just like in your favourite terminal.
Under the hood the program first tokenises the user input, expands shell variables (`$HOME`, `$?`, β¦) and quotes, builds an abstract syntax tree, and finally executes it while respecting Unix semantics for pipes and redirections.
The mandatory scope follows the subject of 42 School exactly; bonus features can be toggled in the Makefile.
---
## π Features
| ποΈ Category | β¨ Details |
|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Built-ins** | `echo`, `cd`, `pwd`, `export`, `unset`, `env`, `exit` |
| **Pipelines `\|`** | Unlimited number of commands connected with pipes (`ls -l \| grep .c \| wc -l`) |
| **Redirections** | `>`, `>>`, `<`, `<<` (here-doc with proper Ctrl-C cancel) |
| **Quoting Rules** | Handles single quotes, double quotes and escaped characters exactly like *bash* |
| **Environment Vars**| `$VAR` / `${VAR}` expansion, `$?` exit-status expansion |
| **Signal Handling** | Ctrl-C interrupts the current command without quitting the shell; Ctrl-\ behaves like *bash*; heredoc aborts cleanly on Ctrl-C |
| **Executable Search** | Respects `PATH`, fallback to relative/absolute paths |
| **Memory-Safe** | No leaks (checked with Valgrind π©»), clean exit on EOF or `exit` |
| **Bonus Switches** | Toggle wildcard expansion, logical operators `&&` / `\|\|`, parentheses and more via **make bonus** (*if implemented*) |
---
## π οΈ Requirements
- **GCC / Clang** supporting C99
- **Make** utility
- **GNU Readline** (mandatory subject requirement)
- **Unix-like OS** (Linux π§ or macOS π tested)
---
## π¦ Installation
```
git clone https://github.com/tigran-sargsyan-w/minishell.git
cd minishell
make # builds mandatory version
# make bonus # builds bonus version (optional)
```
`libft` is included as a git subdirectory and will be built automatically.
---
## βΆοΈ Usage
```
./minishell
minishell$ echo "Hello, World! π"
Hello, World! π
minishell$ ls | grep '\.c$' > sources.txt
minishell$ cat < multi-line
> heredoc
> example
> EOF
multi-line
heredoc
example
minishell$ echo "last exit code was $?"
last exit code was 0
minishell$ exit
```
---
## π How It Works
1. **Lexer** β splits the input line into tokens (words, operators, quoted strings), respecting escaping rules.
2. **Parser** β builds a syntax tree of simple commands, I/O redirections and pipes; performs environment-variable expansion and quote removal.
3. **Executor**
* creates the required number of processes with `fork()`;
* sets up pipes and redirections (`dup2`);
* runs built-ins in the parent process when possible (`cd`, `export`, `exit`);
* waits for the last child and stores its exit status in `$?`.
4. **Signal Layer** β installs custom handlers for `SIGINT` and `SIGQUIT` to mimic *bash* behaviour both in the main prompt and inside heredocs.
5. **Resource Cleanup** β frees every allocated structure and closes all file descriptors before returning to the prompt (or exiting).
---
## ποΈ Repository Layout
```
.
βββ Makefile
βββ include/ # public headers
βββ libft/ # custom C standard-library re-implementation
βββ src/
β βββ builtin/ # shell built-ins
β βββ env/ # env-list abstraction
β βββ executor/ # pipeline & redirection logic
β βββ lexer/ # lexical analyser
β βββ minishell_utils/ # prompt loop, signals, helpers
β βββ parser/ # AST builder and expander
β βββ minishell.c # Entry point
βββ tests/ # markdown specs & scripts for regression tests
```
---
## β
Tests
Below are organized test suites covering all core components of the project:
| π§© Module | π Test Case File | |
|-------------------------|------------------|-----|
| π§ Lexer | [LEXER.md](tests/LEXER.md) | β
|
| π§· Parser | [PARSER.md](tests/PARSER.md) | β
|
| π£οΈ Quotes & Expansion | [QUOTES_AND_EXPANSION.md](tests/QUOTES_AND_EXPANSION.md) | β
|
| π Redirection | [REDIRECTION.md](tests/REDIRECTION.md) | β
|
| βοΈ Executor | [EXECUTOR.md](tests/EXECUTOR.md) | β
|
| π§Ύ Exit Status (`$?`) | [EXIT_STATUS.md](tests/EXIT_STATUS.md) | β
|
---
## π§ͺ Builtin Detection Script
To test **unsupported builtin commands** (i.e., those your minishell is **not required** to implement), run:
```bash
./tests/test_builtins.sh
```
This script will:
- Attempt to run various shell builtins like `source`, `bind`, `declare`, etc.
- Show the output or error for each one.
- Help confirm that your shell gracefully reports errors or ignores unsupported commands.
π Location: `tests/test_builtins.sh`
---
## π§© Troubleshooting
| π Symptom | π οΈ Checklist |
|-----------|--------------|
| **Command not found / wrong binary** | Is your `$PATH` set correctly? Use `env | grep ^PATH=` inside minishell. |
| **Redirection fails with βBad file descriptorβ** | Verify file-descriptor lifetime; ensure you close unused pipe ends. |
| **Ctrl-C kills the whole shell** | Make sure the parent process resets the default handler **after** forking. |
| **Memory leaks reported by Valgrind** | Double-check cleanup of the AST and environment list on each loop iteration. |
| **Heredoc ignores variables** | Variable expansion happens *before* heredoc delimiter matching β re-evaluate your lexer rules. |
---
Happy hacking β may your prompt never segfault! ππ₯