Skip to content
 
 

Latest commit

 

History

69 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

minishell

A bash-like shell with pipes, redirections, heredoc, environment management, and all mandatory builtins.

Language School Type Norm


About

minishell is a group project at 42 reimplementing a simplified Unix shell inspired by bash. It handles user input, tokenisation, expansion, redirection, piped commands, and process execution — while maintaining its own environment state across commands.

Collaborators:

  • bebuber — execution engine, all builtins, signal handling
  • amecani — lexer/parser, tokenisation, expansion, redirection parsing, syntax check

Features

  • Interactive prompt with command history (via readline)
  • Pipes (|) connecting multiple commands
  • Input/output redirections: <, >, >>
  • Heredoc (<<) with delimiter support
  • Environment variable expansion ($VAR, $?)
  • Single and double quote handling
  • Signal handling: ctrl-C, ctrl-D, ctrl-\
  • Full environment management inherited from the parent process

Builtins

Command Behaviour
echo Prints arguments, supports -n flag
cd Changes directory, supports ~ and no-arg (goes to $HOME), updates PWD and OLDPWD
pwd Prints current working directory
export Sets environment variables; prints declare -x format with no args
unset Removes environment variables
env Prints current environment
exit Exits with optional status code (mod 256), validates numeric argument

Structure

minishell/
├── minishell.h          # All structs, enums, prototypes
├── Makefile
├── libft/               # Bundled libft
└── src/
    ├── minishell.c      # Entry point, main loop, terminal setup
    ├── builtins/
    │   ├── cd.c         # cd + PWD/OLDPWD update + get_env_value
    │   ├── echo.c       # echo with -n flag
    │   ├── env.c        # env display + update_env + add_new_env + free_arr
    │   ├── exit.c       # exit + print_error
    │   ├── export.c     # export with declare -x display
    │   ├── pwd.c        # pwd via getcwd
    │   └── unset.c      # unset with env array rebuild
    ├── execution/
    │   ├── execute.c    # Dispatcher: builtin_commands, execute, alloc_env
    │   ├── exe_single.c # Single command: fork, redirect, wait, restore fds
    │   ├── exe_multiple.c # Piped commands: allocate pipes, fork all, wait all
    │   ├── utils.c      # count_commands, pipe helpers, ft_strcmp
    │   └── signal.c     # Signal modes: COMMAND, EXECUTION, HEREDOC
    └── parsing/
        ├── parse.c              # command_center: main parsing pipeline
        ├── extract_token.c      # Tokeniser: quotes, operators, word boundaries
        ├── expand.c             # $VAR and $? expansion
        ├── merge.c              # Token merging for adjacent quoted strings
        ├── syntax_check.c       # Validates token sequence
        ├── redirectioning.c     # Builds t_command list from token list
        ├── redirectioning_v2.c  # Strips redirection tokens from args array
        ├── redirectioning_v3_extra_fucntions.c  # Opens fds for <, >, >>, <<
        ├── utilities.c          # Token/command list traversal and cleanup
        └── utilities_v2.c       # Token and command initialisers

How It Works

Each command cycle in command_center runs through a pipeline:

readline input
    │
    ▼
extract_token     → doubly-linked t_token list
    │
    ▼
expand            → replaces $VAR / $? in token strings
    │
    ▼
merge             → joins adjacent tokens (e.g. "hel"lo → hello)
    │
    ▼
syntax_check      → validates token sequence
    │
    ▼
redirectioning    → builds t_command linked list with args arrays
redirectioning_v2 → opens file descriptors, strips redirection tokens from args
    │
    ▼
execute           → runs single or piped commands

Single command execution saves stdin/stdout with dup, applies redirections, runs the builtin in the parent process or forks for external commands, then restores the original fds.

Multiple commands (pipes) allocates one pipe() per command, forks all children at once, adjusts each child's stdin/stdout to the correct pipe ends, then closes all pipes in the parent and waits for all children.


Data Structures

typedef struct s_token {
    t_type          type;           // WORD, PIPE, IN, OUT, APPEND, H_DOC, EMPTY
    char            *string;
    char            quote;          // '\'' or '"' or 0
    bool            merge_with_next;
    struct s_token  *next;
    struct s_token  *prev;
}   t_token;

typedef struct s_commend {
    char            **args;         // NULL-terminated args array
    int             fd_in;          // -1 if not redirected
    int             fd_out;         // -1 if not redirected
    struct s_commend *next;
    struct s_commend *prev;
}   t_command;

typedef struct s_data {
    char        *input;
    char        **env;
    int         **fd;               // pipe file descriptors
    pid_t       *pid;
    int         exit_code;
    t_command   *cmmds;
    t_token     *token;
}   t_data;

Usage

Requirements

  • readline library (brew install readline on macOS or apt install libreadline-dev on Linux)

Build

make

Run

./minishell
terminal :echo "hello $USER"
hello yourname
terminal :ls -la | grep .c | wc -l
42
terminal :cat < input.txt > output.txt
terminal :export MY_VAR=hello
terminal :echo $MY_VAR
hello
terminal :exit

Makefile Targets

Target Description
make / make all Build minishell binary
make clean Remove object files
make fclean Remove object files and binary
make re fclean + all

Notes

  • Heredoc uses a temporary h_doc.txt file — only one heredoc active at a time.
  • Environment is fully copied from the parent process at startup and managed independently.
  • Exit codes follow bash conventions: 127 for command not found, 128 + signal for signal termination.
  • Written in compliance with the 42 Norm.

42 Heilbronn — Group Project

About

A bash-like shell with pipes, redirections, heredoc, environment variable expansion and all mandatory builtins

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages