SkillAgentSearch skills...

Minishell

[42-Cursus] Minishell is a minimalist shell implementation written in C, designed to mimic basic functionalities of a Unix shell like Bash.

Install / Use

/learn @OliverKingz/Minishell
About this skill

Quality Score

0/100

Category

Design

Supported Platforms

Universal

README

<div align="right">

GitHub stars Visits Badge Created Badge Updated Badge

</div> <div align="center">

minishell_title

</div>

[42-Cursus] Minishell is a minimalist shell implementation written in C, designed to mimic basic functionalities of a Unix shell like Bash. This project focuses on understanding processes, file descriptors, and shell operations such as command execution, redirections, pipes, and signal handling.

<div align="center">

minishell_sync

</div>

Keywords

  • Shell
  • Process Management
  • File Descriptors
  • Redirections
  • Pipes
  • Signal Handling
  • Built-in Commands
  • Environment Variables
<div align="right">

Made by: Contributors Display

</div>

Index


Overview

Minishell is a simplified Unix shell implementation created as part of the 42 Cursus curriculum. The project aims to deepen understanding of core operating system concepts such as process management, file descriptors, and shell operations. Minishell supports basic shell functionalities like command execution, input/output redirection, pipes, and environment variable management. It also handles signals like ctrl-C, ctrl-D, and ctrl-\ similar to Bash.

The project is written in C and adheres to strict coding standards, ensuring no memory leaks and robust error handling. Minishell is a great way to explore the inner workings of a shell and gain hands-on experience with low-level system programming.


Features

  • Command Execution: Executes commands based on the PATH variable or using relative/absolute paths.
  • Input/Output Redirection: Supports <, >, <<, and >> for input/output redirection.
  • Pipes: Implements pipes (|) to connect the output of one command to the input of another.
  • Environment Variables: Expands environment variables (e.g., $HOME) and $? for the exit status of the last command.
  • Signal Handling: Handles ctrl-C, ctrl-D, and ctrl-\ as in Bash.
  • Built-in Commands: Implements built-ins like echo, cd, pwd, export, unset, env, and exit.
  • Quoting: Handles single (') and double (") quotes to prevent interpretation of metacaracters.

Bonus Features (Not implemented)

  • Logical Operators: Supports && and || with parentheses for priority.
  • Wildcards: Implements * wildcard for the current directory.

Requirements

  • The project must be written in C and follow the 42 Norm.
  • No memory leaks are allowed.
  • The shell must handle signals correctly and manage file descriptors properly.
  • The Makefile must compile the project with -Wall, -Werror, and -Wextra flags.
  • The shell must support the mandatory features listed in the subject.

Flowchart

Below is the flowchart representing the architecture and flow of the Minishell project.

Note: This flowchart is an approximation and may not represent the exact implementation details.

graph TB
    direction TB

    subgraph "User Interface"
        Input["Input Handler
        (main, input, shell)"]:::black
    end

    subgraph "Processing Input"
        Lexer["Lexer
        (lexer)"]:::green
        Expansion["Expansion
        (expansion_security, expansion_utils, expansion_var)"]:::green
        Parser["Parser
        (parser_tokenize, parser_utils, token_list, token_utils)"]:::green
    end

    subgraph "Execution"
        subgraph "Redirection Handling"
            Redirection["Input & Output
            (redirections)"]:::turquoise
            Heredocs["Heredocs
            (heredoc, heredoc2)"]:::turquoise
        end
        subgraph "Command Handling"
            Builtin["Builtin Commands
            (builtin, bi_cd, bi_echo, bi_env, bi_exit, bi_export, bi_pwd, bi_unset)"]:::blue
            External["External Commands"]:::blue
        end
        Command["Command Structure
        (cmd, cmd_exit)"]:::dark_blue
        Executor["Executor
        (execution)"]:::black
    end

    subgraph "Foundational Utilities"
        Utility["Utilities
        (utils, utils2, type_check)"]:::orange
        Libft["Libft
        (ft_*)"]:::orange
        Debug["Debug prints
        (prints)"]:::orange
    end

    subgraph "System Interactions"
        Env["Environment
        (env, env_list, env_var)"]:::red
        Signal["Signal Handler
        (signal)"]:::red
    end

    Env --> Input & Expansion & Command & Heredocs
    Signal --> Input & Heredocs & Executor

    Input       -->|"input line"| Lexer
    Lexer       -->|"validated input"| Expansion
    Expansion   -->|"expanded vars"| Parser & Heredocs
    Parser      -->|"tokenized input"| Heredocs & Redirection
    Heredocs    --> Redirection
    Heredocs    -->|"prepared heredocs"| Builtin & External & Command
    Redirection -->|"prepared redirections"| Builtin & External & Command
    Builtin     -->|"built-in execution"| Command
    External    -->|"external execution"| Command
    Command     -->|"execution context"| Executor
    Executor    -->|"wait for input after execution"| Input


    classDef white fill:#ffffff,stroke:#000000,stroke-width:1px,color:#000000;
    classDef black fill:#000000,stroke:#ffffff,stroke-width:1px,color:#ffffff;
    classDef green fill:#80ff80,stroke:#008000,stroke-width:1px,color:#004d00;
    classDef blue fill:#80bfff,stroke:#004080,stroke-width:1px,color:#00264d;
    classDef dark_blue fill:#ffffff,stroke:#004080,stroke-width:1px,color:#00264d;
    classDef turquoise fill:#80ffff,stroke:#008080,stroke-width:1px,color:#004d4d;
    classDef orange fill:#ffcc80,stroke:#ff8000,stroke-width:1px,color:#663300;
    classDef red fill:#ff8080,stroke:#800000,stroke-width:1px,color:#4d0000;

How to Run

  1. Clone this repository:

    git clone [repository-url]
    cd minishell
    
  2. Compile the project:

    make
    
  3. Run the shell:

    ./minishell
    

Parser Example

Input:

cat < in | grep "Hi bye" | grep 'H' > out | cat >> final_out -e

Tokenizer result and classification:

  • "cat": command
  • "<": redir_in
  • "in": file_path
  • "|": op_pipe
  • "grep": command
  • "Hi bye": argument
  • "|": op_pipe
  • "grep": command
  • "H": argument
  • ">": redir_out
  • "out": file_path
  • "|": op_pipe
  • "cat": command
  • ">>": redir_append
  • "final_out": file_path
  • "-e": argument

Recomendations for Testing and Summarized Tests

  1. time: Use time to measure how long commands take to execute in Minishell, especially with commands like sleep. This helps confirm correct handling of concurrency and pipes.
  2. env: Run env inside Minishell to verify that environment variables (like PATH) are correctly inherited and available to child processes.
  3. env -i: Launch Minishell with an empty environment using env -i ./minishell to test its behavior when no environment variables are set.
  4. echo $?: After running commands, use echo $? to check if Minishell correctly sets and updates the exit status.
  5. which ls: Use which within Minishell to confirm that the shell can locate executables using the current PATH.
  6. cp /usr/bin/ls .: Copy a binary like ls to the current directory and run it from Minishell to test support for relative and absolute paths.
  7. unset PATH or export PATH="": Remove or clear the PATH variable in Minishell to ensure it handles missing PATH gracefully (e.g., only absolute/relative paths work).
  8. valgrind --trace-children=yes --track-fds=yes: Run Minishell under Valgrind with these flags to check for memory leaks and proper file descriptor management, including child processes.
  9. strace: Use strace to debug Minishell’s system calls and signal handling.
    • strace -f ./minishell: Track all child processes created by fork().
    • strace -e trace=execve ./minishell: Filter and display only command execution (execve) calls.
    • strace -c ./minishell: Get a summary of all system calls and time spent on each.

| Input Command | Description | | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | ""ec''ho"" "Welcome to our 'minishell', I am $USER" | Prints 'Welcome to our 'minishell', I am <USER>' with mixed quotes.

View on GitHub
GitHub Stars6
CategoryDesign
Updated19d ago
Forks0

Languages

C

Security Score

90/100

Audited on Mar 9, 2026

No findings