{"id":29169341,"url":"https://github.com/tigran-sargsyan-w/minishell","last_synced_at":"2026-04-19T06:32:18.538Z","repository":{"id":289815912,"uuid":"971286563","full_name":"tigran-sargsyan-w/minishell","owner":"tigran-sargsyan-w","description":"This project is about creating a simple shell. Yes, your own little bash. You will learn a lot about processes and file descriptors.","archived":false,"fork":false,"pushed_at":"2025-06-20T09:49:03.000Z","size":428,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-27T15:51:15.233Z","etag":null,"topics":["42","42school","c","c-language","cli","executor","execve","fork","lexer","mandatory","minishell","parser","posix","readline","shell","signals","terminal","unix","unix-shell"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tigran-sargsyan-w.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-23T09:40:57.000Z","updated_at":"2025-06-20T09:46:19.000Z","dependencies_parsed_at":"2025-04-25T07:52:38.352Z","dependency_job_id":"dd56ed9c-17db-41eb-b00f-55605a1ade47","html_url":"https://github.com/tigran-sargsyan-w/minishell","commit_stats":null,"previous_names":["tigran-sargsyan-w/minishell"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tigran-sargsyan-w/minishell","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fminishell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fminishell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fminishell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fminishell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tigran-sargsyan-w","download_url":"https://codeload.github.com/tigran-sargsyan-w/minishell/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fminishell/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262959556,"owners_count":23391055,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["42","42school","c","c-language","cli","executor","execve","fork","lexer","mandatory","minishell","parser","posix","readline","shell","signals","terminal","unix","unix-shell"],"created_at":"2025-07-01T12:00:42.672Z","updated_at":"2026-04-19T06:32:18.491Z","avatar_url":"https://github.com/tigran-sargsyan-w.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Minishell 🐚✨\n\n✅ **Completed**: Mandatory (101/100)  \n\n![42 Logo](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTXfAZMOWHDQ3DKE63A9jWhIqQaKcKqUIXvzg\u0026s)\n\n**Minishell** is a tiny Unix shell written in C for the 42 School curriculum.  \nIt 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.\n\n![Minishell](https://i.ibb.co/GL2Spnf/image.png)\n\n---\n\n## 📚 Table of Contents\n- [Description](#description)\n- [Features](#features)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Usage](#usage)\n- [How It Works](#how-it-works)\n- [Tests](#tests)\n- [Troubleshooting](#troubleshooting)\n\n---\n\n## 📝 Description\n\n`minishell` launches an interactive prompt that lets you execute commands just like in your favourite terminal.  \nUnder 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.  \nThe mandatory scope follows the subject of 42 School exactly; bonus features can be toggled in the Makefile.\n\n---\n\n## 🚀 Features\n\n| 🗂️ Category         | ✨ Details |\n|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **Built-ins**       | `echo`, `cd`, `pwd`, `export`, `unset`, `env`, `exit` |\n| **Pipelines `\\|`**   | Unlimited number of commands connected with pipes (`ls -l \\| grep .c \\| wc -l`) |\n| **Redirections**    | `\u003e`, `\u003e\u003e`, `\u003c`, `\u003c\u003c` (here-doc with proper Ctrl-C cancel) |\n| **Quoting Rules**   | Handles single quotes, double quotes and escaped characters exactly like *bash* |\n| **Environment Vars**| `$VAR` / `${VAR}` expansion, `$?` exit-status expansion |\n| **Signal Handling** | Ctrl-C interrupts the current command without quitting the shell; Ctrl-\\ behaves like *bash*; heredoc aborts cleanly on Ctrl-C |\n| **Executable Search** | Respects `PATH`, fallback to relative/absolute paths |\n| **Memory-Safe**     | No leaks (checked with Valgrind 🩻), clean exit on EOF or `exit` |\n| **Bonus Switches**  | Toggle wildcard expansion, logical operators `\u0026\u0026` / `\\|\\|`, parentheses and more via **make bonus** (*if implemented*) |\n\n---\n\n## 🛠️ Requirements\n\n- **GCC / Clang** supporting C99  \n- **Make** utility  \n- **GNU Readline** (mandatory subject requirement)  \n- **Unix-like OS** (Linux 🐧 or macOS 🍎 tested)\n\n---\n\n## 📦 Installation\n\n```\ngit clone https://github.com/tigran-sargsyan-w/minishell.git\ncd minishell\nmake           # builds mandatory version\n# make bonus   # builds bonus version (optional)\n```\n\n`libft` is included as a git subdirectory and will be built automatically.\n\n---\n\n## ▶️ Usage\n\n```\n./minishell\nminishell$ echo \"Hello, World! 🌍\"\nHello, World! 🌍\nminishell$ ls | grep '\\.c$' \u003e sources.txt\nminishell$ cat \u003c\u003cEOF\n\u003e multi-line\n\u003e heredoc\n\u003e example\n\u003e EOF\nmulti-line\nheredoc\nexample\nminishell$ echo \"last exit code was $?\"\nlast exit code was 0\nminishell$ exit\n```\n\n---\n\n## 🔍 How It Works\n\n1. **Lexer** — splits the input line into tokens (words, operators, quoted strings), respecting escaping rules.  \n2. **Parser** — builds a syntax tree of simple commands, I/O redirections and pipes; performs environment-variable expansion and quote removal.  \n3. **Executor**  \n   * creates the required number of processes with `fork()`;  \n   * sets up pipes and redirections (`dup2`);  \n   * runs built-ins in the parent process when possible (`cd`, `export`, `exit`);  \n   * waits for the last child and stores its exit status in `$?`.  \n4. **Signal Layer** — installs custom handlers for `SIGINT` and `SIGQUIT` to mimic *bash* behaviour both in the main prompt and inside heredocs.  \n5. **Resource Cleanup** — frees every allocated structure and closes all file descriptors before returning to the prompt (or exiting).\n\n---\n\n## 🗄️ Repository Layout\n\n```\n.\n├── Makefile\n├── include/          # public headers\n├── libft/            # custom C standard-library re-implementation\n├── src/\n│   ├── builtin/      # shell built-ins\n│   ├── env/          # env-list abstraction\n│   ├── executor/     # pipeline \u0026 redirection logic\n│   ├── lexer/        # lexical analyser\n│   ├── minishell_utils/ # prompt loop, signals, helpers\n│   ├── parser/       # AST builder and expander\n│   └── minishell.c   # Entry point\n└── tests/            # markdown specs \u0026 scripts for regression tests\n```\n---\n\n## ✅ Tests\n\nBelow are organized test suites covering all core components of the project:\n\n| 🧩 Module                | 🔗 Test Case File |    |\n|-------------------------|------------------|-----|\n| 🧠 Lexer                | [LEXER.md](tests/LEXER.md) | ✅ |\n| 🧷 Parser               | [PARSER.md](tests/PARSER.md) | ✅ |\n| 🗣️ Quotes \u0026 Expansion  | [QUOTES_AND_EXPANSION.md](tests/QUOTES_AND_EXPANSION.md) | ✅ |\n| 🔀 Redirection         | [REDIRECTION.md](tests/REDIRECTION.md) | ✅ |\n| ⚙️ Executor            | [EXECUTOR.md](tests/EXECUTOR.md) | ✅ |\n| 🧾 Exit Status (`$?`)  | [EXIT_STATUS.md](tests/EXIT_STATUS.md) | ✅ |\n\n---\n\n## 🧪 Builtin Detection Script\n\nTo test **unsupported builtin commands** (i.e., those your minishell is **not required** to implement), run:\n\n```bash\n./tests/test_builtins.sh\n```\n\nThis script will:\n- Attempt to run various shell builtins like `source`, `bind`, `declare`, etc.\n- Show the output or error for each one.\n- Help confirm that your shell gracefully reports errors or ignores unsupported commands.\n\n📎 Location: `tests/test_builtins.sh`\n\n---\n\n## 🧩 Troubleshooting\n\n| 😖 Symptom | 🛠️ Checklist |\n|-----------|--------------|\n| **Command not found / wrong binary** | Is your `$PATH` set correctly? Use `env | grep ^PATH=` inside minishell. |\n| **Redirection fails with “Bad file descriptor”** | Verify file-descriptor lifetime; ensure you close unused pipe ends. |\n| **Ctrl-C kills the whole shell** | Make sure the parent process resets the default handler **after** forking. |\n| **Memory leaks reported by Valgrind** | Double-check cleanup of the AST and environment list on each loop iteration. |\n| **Heredoc ignores variables** | Variable expansion happens *before* heredoc delimiter matching — re-evaluate your lexer rules. |\n\n---\n\nHappy hacking — may your prompt never segfault! 🐚💥\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigran-sargsyan-w%2Fminishell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftigran-sargsyan-w%2Fminishell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigran-sargsyan-w%2Fminishell/lists"}