Skip to main content

What is Minishell?

Minishell is a lightweight Unix shell implementation written in C that recreates the core functionality of bash. It provides an interactive command-line interface for executing commands, managing processes, and handling input/output redirection.
Minishell is built as a learning project to understand how Unix shells work under the hood, including process management, file descriptors, and command parsing.

Key Features

Built-in Commands

Execute essential shell built-ins like echo, cd, pwd, export, unset, and env without forking processes.

Pipeline Support

Chain multiple commands together using pipes (|) to redirect output from one command to another.

I/O Redirection

Redirect input and output using <, >, >>, and heredoc (<<) operators for flexible data flow.

Environment Variables

Expand environment variables with $VAR syntax and manage shell environment with export and unset.

Signal Handling

Properly handle Ctrl+C (SIGINT) and Ctrl+\ (SIGQUIT) signals for interactive shell control.

Command History

Navigate through previously executed commands using readline’s history feature.

Core Capabilities

Command Execution

Minishell executes both built-in commands and external programs by searching the system’s PATH environment variable:
// From main.c - Main shell loop
while (argc && argv)
{
    prompt = ft_print_user();
    line = readline(prompt);
    free(prompt);
    if (!line)
        ft_exit (NULL, 1);
    if (exist(line))
        enterdata(line, data, -1);
}

Built-in Commands

The shell implements seven essential built-in commands:
  • echo - Display text with optional -n flag
  • cd - Change the current working directory
  • pwd - Print the current working directory
  • export - Set environment variables
  • unset - Remove environment variables
  • env - Display all environment variables
  • exit - Exit the shell

Process Management

Minishell handles process execution using fork() and execve() system calls:
// From ft_execute_commands.c - Child process execution
if (execve(node->full_path, node->full_cmd, data->execute_envp) == -1)
{
    write(1, node->full_cmd[0], ft_strlen(node->full_cmd[0]));
    write(1, " : comand not found\n", 20);
    exit (127);
}

What’s Supported vs. Not Supported

  • Single and multiple command execution
  • Pipes (|) for command chaining
  • Input redirection (<)
  • Output redirection (> and >>)
  • Heredoc (<<)
  • Environment variable expansion ($VAR, $?)
  • Single and double quote handling
  • Exit status management ($?)
  • Signal handling (Ctrl+C, Ctrl+D, Ctrl+)
  • Command history (up/down arrows)
  • Logical operators (&&, ||)
  • Wildcards (*, ?, [])
  • Background processes (&)
  • Subshells (())
  • Command substitution (`command` or $(command))
  • Arithmetic expansion ($((...)))
  • Job control (jobs, fg, bg)
  • Aliases
  • Shell scripting (only interactive mode)

Architecture Overview

Minishell is organized into several key components:
  1. Input Parsing - Reads and tokenizes user input, handling quotes and special characters
  2. Command Preparation - Creates execution nodes for each command in a pipeline
  3. Path Resolution - Locates executable files in the system PATH
  4. Execution Engine - Manages process creation, pipes, and I/O redirection
  5. Built-in Handler - Executes shell built-in commands directly
// From minishell.h - Main data structure
typedef struct s_mini
{
    char        **commands;      // Parsed command tokens
    char        *full_path;      // Path to executable
    int         splits;          // Number of tokens
    int         ft_count_pipes;  // Number of pipes
    char        **execute_envp;  // Environment variables
    t_node      **nodes;         // Execution nodes
    int         nbr_nodes;       // Number of commands
    char        **bin_path;      // PATH directories
    t_prompt    *env;            // Environment list
} t_mini;

Getting Started

Ready to start using Minishell? Follow these guides:

Installation

Build Minishell from source and verify your installation

Quick Start

Learn basic commands and try your first pipeline

Exit Status

Minishell maintains an exit status variable (g_status) that stores the return code of the last executed command:
// From main.c - Global status variable
int g_status = 0;
You can access this value using $? in your commands, just like in bash.

Build docs developers (and LLMs) love