The Minishell project is designed to master process management, command execution, and handling signals in C. It requires understanding of Unix/Linux system calls, particularly those related to process creation, communication between processes (pipes), and signal handling. It implements redirections and pipes, as well as environment variable expansions and the cd, echo, env, exit, export, pwd and unset builtin commands.
- Install the dependencies
sudo apt update && sudo apt install make git gcc lib32readline8 lib32readline-dev- Clone the repository
git clone git@github.com:ahlyel-amine/Mini_Shell.git && cd Mini_Shell- To compile Run
make
- If you have docker simply run
docker compose run --rm minibash
To compile:
makeTo run the program:
./minishellyou can simply run if you have docker installed
docker compose run --rm minishellA prompt will appear. You may enter your commands to be executed.
Minishell is a miniature shell program based on Bash. It supports the following features:
- Prompt Display: Minishell displays a prompt indicating readiness for user input.
- Command History: Users can navigate command history using the up and down arrow keys.
- System Executables: System executables available from the environment (e.g., ls, cat, grep).
- Local Executables: Ability to execute local executables using relative or absolute paths (e.g., ./minishell).
- Builtin Commands:
echowith option-n.cdwith only a relative or absolute path.pwdwith no options.exportwith no options.unsetwith no options.envwith no options or arguments.exitwith exit number but no other options.
- AND and OR Operators: Support for
&&and||operators with priority using()parentheses. - Wildcards: Use of
*as wildcards. - Pipes: Redirect output from one command to input for the next using the
|operator. - Redirections:
>: Redirects output.>>: Redirects output in append mode.<: Redirects input.<< DELIMITER: Displays a new prompt, reads user input until reaching DELIMITER, redirects user input to command input (does not update history).
- Subshell: Support for subshells using
()parentheses. - Environment Variables: Expansion of environment variables (e.g., $USER or $VAR) to their values.
- $? Expansion: Expands to the exit status of the most recently executed foreground pipeline.
- User Keyboard Signals:
ctrl-c: Displays a new prompt line.ctrl-d: Exits Minishell.ctrl-\: Does nothing.
Minishell does not support the following:
- \ (Backslash): Not supported for escaping characters.
- ; (Semicolon): Not supported as a command separator.
Please note that Minishell aims to provide a lightweight shell experience with essential functionalities. If you have any questions or suggestions, feel free to reach out!
This project has given you a deep understanding of how a shell works and has helped you develop your skills in various areas:
- Process Management: Creating new processes using
fork(), and executing commands usingexecve(). - File Descriptors and Redirection: Manipulating file descriptors to implement redirection (
>,>>,<,<< DELIMITER) using system calls likedup2()andpipe(). - Signal Handling: Handling signals like
SIGINT(Ctrl-C),SIGQUIT(Ctrl-), andEOF(Ctrl-D) usingsignal()orsigaction(). - String Manipulation: Parsing command line input, handling special characters like
*(wildcards), and expanding environment variables ($VAR) and the special variable$?. - Builtin Commands: Implementing builtin commands (
echo,cd,pwd,export,unset,env,exit) using system calls and other functions. - Heredoc Redirection (
<< DELIMITER): Reading user input until a specific delimiter is reached and redirecting it to command input. - Execution Tree for Logical Operators (
&&,||) and Subshells (()): Parsing the command line input into an execution tree to handle logical operators and subshells correctly, likely involving recursive parsing and execution.
Parsing is a critical component of the Minishell project. It involves transforming the user's input into a structured format that can be processed for execution. In this implementation, the input line is converted into a tokenized linked list, which is looped through like a tree structure. The parsing is completed during this loop.
Tokenization is a sub-component of parsing. It breaks down the input string into meaningful tokens, such as commands, arguments, and operators. These tokens are then organized into a linked list. This tokenized linked list is crucial for identifying and categorizing tokens based on their content and position in the input string.
After the tokenized linked list is created and parsing is completed during the loop, Minishell executes the identified commands. Each tree trunk in the loop represents a command execution point, handling input/output redirection, pipes, subshells, and logical operations like && and ||. This involves creating new processes for each command, managing input/output redirection, and handling signals for graceful termination.
Proper error handling and resource cleanup are essential for a robust shell application. The Minishell project includes mechanisms to catch and report errors, ensure that resources are freed appropriately, and maintain the integrity of the shell environment.
- Environment Variables Management: The shell maintains and manipulates environment variables, allowing users to customize their shell experience.
- Signal Handling: The Minishell implements signal handling to allow users to interrupt and terminate processes gracefully.
- Process Management: The shell creates and manages child processes for executing commands, demonstrating the principles of process synchronization and communication.
- Implementing signal handling for interrupting and terminating processes gracefully.
- Supporting job control features like foreground and background jobs.
- Enhancing the shell with scripting capabilities.
