Minishell_42 is a simplified shell program designed to mimic the behavior of a UNIX shell. It is a part of the 42 Network curriculum and is meant to help students learn about the core functionalities of shell commands, environment variables, and process management. The project involves implementing a shell from scratch, providing fundamental shell features such as command parsing, file redirection, environment variable expansion, command execution, and more.
- Command Parsing: The shell parses user input and interprets commands.
- Environment Variables: Support for handling environment variables like
$HOME,$PATH, etc. - Process Management: Executes commands in a separate process and supports piping and redirection.
- Built-in Commands: Implements common shell built-ins like
cd,echo,exit,pwd,export,unset, andenv. - File Redirection: Handles file redirection for input/output, including
>,>>, and<. - Piping: Supports piping between commands using
|. - Herodoc: Implements heredoc functionality to handle multi-line input redirection.
- Project Structure
- Compilation & Installation
- Usage
- Key Components
- Built-in Commands
- Parser
- Execution
- Memory Management
- Error Handling
- Contributing
This project is organized into multiple directories and files, each serving a specific purpose:
- src/: Contains the core functionality of the shell program.
- lib/: Includes helper functions used throughout the project, such as string manipulation, memory management, and utility functions.
- memory/: Implements memory management utilities for efficient handling of dynamic memory.
- components/: A collection of smaller submodules, each dedicated to specific parts of the shell (like parsing, lexer, execution).
- parser/: Responsible for breaking down the input commands into tokens and interpreting them.
- prompt/: Handles user input and displays the shell prompt.
- lexer/: Implements the lexical analyzer, converting raw input into structured tokens.
- expander/: Expands environment variables and handles command substitution.
- herdoc/: Handles heredoc functionality.
- execution/: Executes commands and manages processes.
- env/: Manages environment variables.
- builtin/: Implements built-in shell commands like
cd,echo,exit, etc. - execute/: Handles the execution flow, including file redirection and pipes.
- Makefile: Automates the build process, defining how to compile and link the project.
- minishell.h: The header file containing declarations for the main program functions.
- execution.h: Declares functions related to command execution.
- parser.h: Defines functions for parsing user input and handling syntax.
- lib/ft_*.c: Functions that provide basic utilities such as string manipulation (e.g.,
ft_atoi.c,ft_strncpy.c,ft_strlen.c, etc.). - parser/parser.c: Main file responsible for parsing the input.
- lexer/lexer.c: Handles lexical analysis of user input.
- expander/expander.c: Expands variables and processes them before execution.
- execution/execution.c: Executes commands and processes.
- builtin/builtin.c: Handles built-in commands (e.g.,
echo,pwd,cd, etc.).
- C Compiler (e.g., GCC or Clang)
- Make (to build the project)
- Unix-like system (Linux/macOS)
- Clone the repository:
git clone https://github.com/iaceene/Minishell_42.git
cd Minishell_42- Build the project using
Makefile:
make- To clean the build files:
make clean- To remove all generated files (including binaries):
make fclean- To recompile everything:
make reAfter compiling the project, you can run the shell program with:
./minishellThis will start an interactive shell where you can enter commands.
Once the shell is running, you can type Unix commands, and it will execute them just like any other shell. Here are some basic features:
-
Command Execution: You can run programs by typing their name (e.g.,
ls,pwd). -
Piping: You can chain commands using pipes (
|).echo "hello" | tr "a-z" "A-Z"
-
Redirection: Input and output redirection works with
>,>>, and<.echo "Hello" > output.txt cat < output.txt
-
Built-in Commands: These commands are built into the shell and don’t require external binaries:
cd: Change directory.echo: Print text to standard output.exit: Exit the shell.pwd: Print working directory.export: Set environment variables.unset: Remove environment variables.env: Print all environment variables.
$ ./minishell
$ echo "Hello World"
Hello World
$ ls
src lib memory components parser prompt lexer expander execution env builtin
$ cd src
$ ./minishell
$ echo $PWD
/home/user/minishell/srcThe parser takes user input and splits it into tokens (commands, arguments, and operators). It checks for valid syntax and prepares the data for execution.
The lexer breaks down the input string into tokens such as words, operators, and symbols. It plays a crucial role in interpreting the user’s intentions.
The expander is responsible for replacing variables in the commands, such as $PATH or $HOME, with their actual values from the environment.
The execution component is responsible for forking new processes, redirecting input/output, handling pipes, and executing commands. It uses system calls like execve() and fork().
Efficient memory management is implemented using custom memory tracking functions to avoid leaks. Dynamic memory allocation is handled manually.
The following built-in commands are implemented:
- cd: Changes the current directory.
- echo: Prints a message to the standard output.
- exit: Exits the shell.
- pwd: Prints the current working directory.
- export: Sets environment variables.
- unset: Removes environment variables.
- env: Lists all environment variables.
$ cd /home/user/projects
$ pwd
/home/user/projectsThe shell ensures that errors are caught at every stage:
- Syntax Errors: If the user inputs a command with invalid syntax, an error message is displayed.
- Command Not Found: If a command doesn’t exist or is incorrectly typed, the shell will print an error message.
- Memory Errors: If memory allocation fails, the program gracefully exits with an error message.
If you'd like to contribute to Minishell_42, feel free to fork the repository and submit a pull request. Please make sure to:
- Follow the coding standards used throughout the project.
- Provide clear and concise commit messages.
- Write tests where applicable.
This project is licensed under the MIT License - see the LICENSE file for details.