Skip to content

GinaldoFT/minishell

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Minishell Documentation

1. Project Overview

Minishell is a project from the 42 school curriculum that consists of creating a simple shell, similar to bash. The main goal is to understand the inner workings of a shell, including process creation, file descriptors, pipes, redirections, and environment variables.

This document provides a detailed explanation of the project's structure, implementation, and features.

2. Features

  • Command Execution: Executes simple and complex commands with arguments.
  • Pipes: Supports multiple pipes (e.g., ls -l | grep minishell | wc -l).
  • Redirections:
    • Input redirection: <
    • Output redirection: >
    • Append output redirection: >>
    • Here document: <<
  • Environment Variables:
    • Expansion of environment variables (e.g., $HOME, $PATH).
    • Correct handling of $? to get the exit status of the last command.
  • Built-in Commands:
    • echo with the -n option.
    • cd with relative or absolute paths.
    • pwd to print the current working directory.
    • export to manage environment variables.
    • unset to remove environment variables.
    • env to print the environment variables.
    • exit to terminate the shell.
  • Signal Handling:
    • Ctrl-C: Interrupts the current process and displays a new prompt.
    • Ctrl-D: Exits the shell.
    • Ctrl-\\: Does nothing.
  • Syntax Validation: Checks for syntax errors before executing commands.
  • Unclosed Quotes: Handles unclosed single and double quotes.

3. Compilation and Execution

Compilation

To compile the project, simply run the make command in the root directory:

make

This will create the minishell executable.

Execution

To run the shell, execute the following command:

./minishell

4. Project Structure

The project is organized into the following directories and files:

  • includes/: Contains the header files for the different modules of the project.
    • minishell.h: Main header file with the primary data structures.
    • parser.h: Header file for the parsing module.
    • execution.h: Header file for the execution module.
    • redirections.h: Header file for the redirections module.
    • builtins.h: Header file for the built-in commands.
    • types.h: Type definitions for the main structures.
  • srcs/: Contains the source code for the project, organized into subdirectories.
    • minishell.c: The main file with the entry point and the main loop of the shell.
    • parser/: Contains the code for parsing the input line, including tokenization, variable expansion, and quote handling.
    • execution/: Contains the code for executing commands, managing processes, and handling pipes.
    • redirections/: Contains the code for handling input and output redirections.
    • builtins/: Contains the implementation of the built-in commands.
  • libft/: Contains a custom library with utility functions.
  • Makefile: The makefile for compiling the project.

5. Core Concepts

5.1. Main Loop

The main loop of the shell is in the main function in srcs/minishell.c. It performs the following steps in a continuous loop:

  1. Read Input: Reads a line from the user using the readline library.
  2. Handle Unclosed Quotes: Checks for unclosed quotes and prompts the user for more input if necessary.
  3. Tokenization: The input line is broken down into a list of tokens. Each token has a type (e.g., word, pipe, redirection) and a value.
  4. Syntax Validation: The list of tokens is checked for syntax errors (e.g., a pipe at the beginning of the line).
  5. Parsing: The tokens are processed to create a list of commands to be executed. This includes expanding environment variables and handling quotes.
  6. Execution: The commands are executed. This may involve creating child processes, setting up pipes, and handling redirections.
  7. Cleanup: Memory allocated for the current command is freed.

5.2. Parsing

The parsing module is responsible for converting the raw input line into a structured representation that can be executed.

  • Tokenization: The tokenize function in srcs/parser/tokenize.c splits the input line into tokens. It recognizes words, pipes (|), and redirection operators (<, >, <<, >>).
  • Variable Expansion: The expand_word function in srcs/parser/expand.c handles the expansion of environment variables (e.g., $HOME).
  • Quote Handling: The shell correctly handles single and double quotes. Characters inside single quotes are treated literally, while variables are expanded inside double quotes.

5.3. Execution

The execution module is responsible for running the parsed commands.

  • Command Creation: The create_cmds function in srcs/execution/create_cmds.c creates a list of t_cmds structures, where each structure represents a simple command.
  • Process Management: For external commands, the shell creates a child process using fork. The child process then executes the command using execve.
  • Pipes: If the command contains pipes, the shell creates a pipe for each | and connects the standard output of one command to the standard input of the next.
  • Built-in Commands: Built-in commands are executed directly in the main process, except when they are part of a pipeline.

5.4. Redirections

The redirections module handles input and output redirections.

  • File Descriptors: The shell manipulates file descriptors to redirect the input and output of commands.
  • Here Documents: For here documents (<<), the shell reads input from the user until a delimiter is found and stores it in a temporary file. This file is then used as the standard input for the command.

6. Data Structures

  • t_geral: The main structure that holds all the important data for the shell, such as the environment variables, the list of tokens, and the list of commands.
  • t_token: Represents a token from the input line. It has a type, a value, and information about quotes.
  • t_cmds: Represents a simple command. It contains the command arguments, the path to the executable, and the file descriptors for input and output.
  • t_env: A linked list that stores the environment variables.

7. Built-in Commands

  • echo [-n]: Prints its arguments to the standard output. The -n option suppresses the trailing newline.
  • cd [path]: Changes the current directory.
  • pwd: Prints the current working directory.
  • export [name[=value]] ...: Sets environment variables. If no arguments are given, it prints a list of all environment variables.
  • unset [name] ...: Removes environment variables.
  • env: Prints the environment variables.
  • exit [n]: Exits the shell with an optional exit status.

8. Error Handling

The shell has a robust error handling mechanism. It prints clear error messages to the standard error stream when something goes wrong, such as:

  • Command not found.
  • No such file or directory.
  • Permission denied.
  • Syntax errors.

The shell also sets the exit status ($?) appropriately after each command.

9. Authors

About

minishell is a shell implementation project from the 42 curriculum.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •