Minishell is a 42 school project that challenges you to recreate a simplified UNIX shell. This implementation supports pipes, redirections, environment variables, and other essential shell features - all while being limited to a select group of standard functions.
Realized by Androlink && WaRtr0
- Clone with submodules:
git clone --recursive https://github.com/WaRtr0/Minishell.git cd Minishell
- Build:
make
- Run:
./minishell
Command | Options Supported |
---|---|
echo |
-n (no newline) |
cd |
Relative/Absolute paths |
pwd |
No options |
export |
Variable assignment |
unset |
Variable removal |
env |
No arguments |
exit |
Exit with status code |
Operator | Example |
---|---|
< (Input) |
grep 'test' < file.txt |
> (Output) |
ls > output.txt |
>> (Append) |
echo "text" >> file.txt |
<< (Here doc) |
cat << LIMITER |
| (Pipe) |
ls | grep .c |
&& (And) |
make && ./app |
|| (Or) |
invalid_cmd || echo "Error" |
() (Grouping) |
(ls || echo Fail) && echo Done |
- Handles unclosed quotes/multiline commands
- Ctrl+C: New prompt on fresh line
- Ctrl+D: Clean exit
- Non-blocking Ctrl+\
You can compile Minishell in debug mode using the following command:
make debug
This enables DEBUG_MODE
, which prints the Abstract Syntax Tree (AST) of the parsed command in a structured JSON format — useful for debugging and understanding how the shell interprets your input.
For the command:
echo hello world! && true && (false || echo hello) && echo 1 | echo 2 | echo * > test
The AST will be displayed in JSON like this:
Click to show AST output (JSON)
[
{
"type": "14-CMD_JOIN",
"content": [
{ "type": "13-CMD_TEXT", "content": "echo" },
{ "type": "16-CMD_EMPTY" },
{ "type": "13-CMD_TEXT", "content": "hello" },
{ "type": "16-CMD_EMPTY" },
{ "type": "13-CMD_TEXT", "content": "world!" },
{ "type": "16-CMD_EMPTY" }
]
},
{
"type": "6-CMD_AND_IF",
"content": [
{
"type": "14-CMD_JOIN",
"content": [
{ "type": "13-CMD_TEXT", "content": "true" },
{ "type": "16-CMD_EMPTY" }
]
}
]
},
{
"type": "6-CMD_AND_IF",
"content": [
{
"type": "10-CMD_PARENTHESIS",
"content": [
{
"type": "14-CMD_JOIN",
"content": [
{ "type": "13-CMD_TEXT", "content": "false" },
{ "type": "16-CMD_EMPTY" }
]
},
{
"type": "8-CMD_OR",
"content": [
{
"type": "14-CMD_JOIN",
"content": [
{ "type": "13-CMD_TEXT", "content": "echo" },
{ "type": "16-CMD_EMPTY" },
{ "type": "13-CMD_TEXT", "content": "hello" }
]
}
]
}
]
}
]
},
{
"type": "6-CMD_AND_IF",
"content": [
{
"type": "0-CMD_PIPE",
"content": [
{
"type": "14-CMD_JOIN",
"content": [
{ "type": "13-CMD_TEXT", "content": "echo" },
{ "type": "16-CMD_EMPTY" },
{ "type": "13-CMD_TEXT", "content": "1" },
{ "type": "16-CMD_EMPTY" }
]
},
{
"type": "14-CMD_JOIN",
"content": [
{ "type": "13-CMD_TEXT", "content": "echo" },
{ "type": "16-CMD_EMPTY" },
{ "type": "13-CMD_TEXT", "content": "2" },
{ "type": "16-CMD_EMPTY" }
]
},
{
"type": "14-CMD_JOIN",
"content": [
{ "type": "13-CMD_TEXT", "content": "echo" },
{ "type": "16-CMD_EMPTY" },
{ "type": "17-CMD_WILDCARD" },
{ "type": "16-CMD_EMPTY" },
{ "type": "2-CMD_REDIR_OUT", "content": 0 }, // init 0
{ "type": "16-CMD_EMPTY" },
{ "type": "13-CMD_TEXT", "content": "test" } // name file
]
}
]
}
]
}
]
- Limited functions
- Only 1 global variable allowed
- Strict 42 norm
- Zero memory leaks