Minishell is a group project with the objective of replicating a Unix shell that mimics Bash’s fundamental behavior. This project provides a hands-on approach to understanding how command interpretation, parsing, and execution are handled in real-world shells. It incorporates key functionalities such as command history, signal management, input/output redirections, and the parsing and execution of commands through, in our case, with an Abstract Syntax Tree (AST).
The following system functions and libraries are permitted in the development of Minishell, in accordance with the project guidelines:
| Category | Functions |
|---|---|
| Readline | readline, rl_clear_history, rl_on_new_line, rl_replace_line, rl_redisplay, add_history |
| Standard I/O | printf, write |
| Memory Management | malloc, free |
| File Operations | access, open, read, close, unlink |
| Directory Operations | opendir, readdir, closedir |
| Process Management | fork, wait, waitpid, wait3, wait4, execve |
| Pipes and Redirections | dup, dup2, pipe |
| Signals | signal, sigaction, kill |
| Error Reporting | strerror, perror |
| Terminal Management | isatty, ttyname, ttyslot, ioctl |
| Environment Access | getenv |
| Termcap Library | tcsetattr, tcgetattr, tgetent, tgetflag, tgetnum, tgetstr, tgoto, tputs |
| Stat Functions | stat, lstat, fstat |
| Exit | exit |
The use of the custom library libft is permitted to facilitate development. This library includes additional utility functions designed for memory management, string manipulation, and more.
Note: Adherence to the allowed functions is crucial for the project's compliance. Any usage of non-permitted functions will lead to non-conformity with the project's requirements.
- Interactive Command Prompt: Displays a prompt, waits for user input, and processes commands.
- Command History: Maintains a functional history allowing users to navigate and execute previous commands.
- Executable Search: Identifies and runs executables from the system’s
PATHor through provided relative and absolute paths. - Redirection Handling: Supports input (
<), output (>), append (>>), and heredoc (<<) redirections. - Variable Expansion: Expands environment variables prefixed with
$. - Quoting Mechanism:
- Single quotes (
'): Disable interpretation of all enclosed metacharacters. - Double quotes (
"): Disable interpretation except for the$symbol for variable expansion.
- Single quotes (
- Signal Handling: Manages signals effectively without relying on global variables, ensuring modular and maintainable code.
- AST Construction and Parsing: Uses an Abstract Syntax Tree to parse and execute complex command structures.
Minishell strives to replicate essential features of Bash, adhering to its syntax and command behavior. While it is not a full Bash implementation, Minishell includes the core aspects that are necessary for typical command-line usage:
- Execution Behavior: Commands are processed similarly to Bash, with support for built-in commands and external executables.
- Pipes and Redirections: Minishell correctly interprets and executes pipes (
|) and redirections, allowing for command chaining and output management. - Environment Variables: Supports basic variable expansion and environmental variable access as Bash does.
- Error Handling: Implements basic error reporting to inform users of invalid commands or issues with execution.
However, due to the educational nature of the project, advanced Bash features such as job control, process substitution, and complex shell scripting are beyond its scope.
An Abstract Syntax Tree (AST) is a tree representation of the abstract syntactic structure of code or commands. In Minishell, the AST is central to parsing and executing commands efficiently. Each node in the tree represents a command, redirection, or a control structure such as a pipe.
- Parsing Input: The input command line is parsed into tokens, distinguishing between commands, arguments, operators, and special symbols.
- Building the AST: Tokens are structured into an AST, where each node represents a logical component of the command. For instance, a pipe operator (
|) splits commands into left and right subtrees. - Execution: The tree is traversed recursively, executing commands based on their position and relationship in the tree.
- Structured Parsing: Simplifies parsing by breaking down complex commands into manageable subunits.
- Execution Order: Ensures commands are executed in the correct order, supporting nested and complex command combinations.
- Error Management: Provides a clear structure for handling syntax errors during parsing.
An input like:
echo "hello" | grep "h" > output.txt
would be parsed into an AST with:
- A root node representing the pipe (
|). - The left child node representing
echo "hello". - The right child node representing the redirection (
>), withgrep "h"as its subnode andoutput.txtas the output target.
Minishell can use the following system functions, aligning with project constraints:
readline,add_history,malloc,free,write,fork,execve,pipe,dup2,open,close,wait,kill,getcwd,chdir,isatty, among others.
- libft: The custom library
libftcan be used for utility functions.
src/: Source code files, including parsing, execution, and utility functions.include/: Header files defining structures and function prototypes.Makefile: For compilation and dependency management.
To compile Minishell, run:
make
This will create an executable named minishell. To run it:
./minishell
Minishell supports basic shell operations such as:
- Executing commands: Run system commands and custom-built commands.
- Command chaining: Use pipes (
|) to chain commands and redirections for output/input management. - Environment variable expansion: Utilize variables prefixed with
$. - Quoting: Use single or double quotes for strings.
Developing Minishell has been an extensive learning experience, emphasizing in gaining practical knowledge of fork, execve, and process management. Ensuring efficient use of malloc and free to avoid memory leaks. Creating reusable and maintainable code by adhering to project constraints (e.g., 1 global variable allowed) and implementing an AST to handle complex command syntax efficiently. The project provided invaluable insights into how shells work under the hood, enhancing our understanding of operating systems, process management, and command-line interfaces.

