Skip to content

mathish06/42sh-workspace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

315 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

42sh

A fully-featured Unix shell written in C — Epitech project (TEK1)


Table of Contents


Overview

42sh is a POSIX-inspired Unix shell implemented from scratch in C. It supports command execution, piping, redirections, environment management, history, aliases, tab-completion, and more — all without relying on readline or any external shell library.

This project was developed as part of the Epitech TEK1 shell programming module.


Features

Category Description
Command execution Fork/exec with full PATH resolution
Pipelines Multi-stage | pipelines
Redirections >, >>, <, << (heredoc)
Logic operators && and || short-circuit evaluation
Command separator ; sequential execution
History Arrow key navigation, !-event expansion, persistent ~/.42sh_history
Aliases Define, list, remove, and auto-expand command aliases
Tab completion Context-aware completion for commands and file paths with interactive menu
Variable expansion $VAR, $?, $HOME, etc.
Backtick expansion `cmd` substitution
Globbing * wildcard expansion
Quotes Single ' and double " quote handling
Dynamic prompt Colored prompt showing last exit status and current directory
Raw mode Terminal raw-mode line editor (no external library)
Signal handling Graceful handling of SIGINT, SIGSEGV, SIGFPE

Architecture

The shell is structured around a classic lexer → parser → AST → executor pipeline:

Input line
    │
    ▼
 Lexer            (src/parsing/lexer.c)
    │  token list
    ▼
 Parser / AST     (src/parsing/tree.c)
    │  ast_node_t tree
    ▼
 Executor         (src/execution/exec_ast.c)
    ├── Builtins  (src/execution/handle_builtins.c)
    ├── Pipes     (src/execution/exec_pipe.c)
    └── Redirs    (src/execution/exec_redir.c)

Pre-execution expansions (history events, backticks, variables, aliases, globs) are applied before the AST is executed.


Getting Started

Prerequisites

  • GCC or a compatible C compiler (epiclang alias used in the Makefile)
  • make
  • libncurses-dev (for terminal handling)
  • libcriterion-dev (optional, for unit tests)
  • gcovr (optional, for coverage)

Build

# Clone the repository
git clone <your-repo-url>
cd 42sh

# Set up git hooks (recommended)
make setup

# Build the library and binary
make

The binary 42sh will be generated in the project root.

Usage

# Interactive mode
./42sh

# Non-interactive / script mode
echo "ls -la" | ./42sh

Built-in Commands

Command Description
cd [path] Change directory; supports ~, - (previous dir), and CDPATH
env Print all exported environment variables
setenv VAR [value] Set (or display) an environment variable
unsetenv VAR ... Remove one or more environment variables
set List all variables (exported and local)
unset VAR ... Remove local shell variables
alias [name[=value]] Define or list aliases
unalias name ... Remove aliases
which cmd Show the resolved path of a command
where cmd Show all locations of a command (builtins + PATH)
repeat N cmd Execute a command N times
exit Exit the shell

Shell Features

History

  • Up/Down arrow keys navigate command history.
  • !n — run the nth history event.
  • !prefix — run the last command starting with prefix.
  • !! — repeat the last command.
  • History is saved to ~/.42sh_history on exit and loaded on start (up to 500 entries).

Tab Completion

Press Tab to auto-complete:

  • Commands — searches PATH for matching executables and built-ins.
  • Paths — completes file and directory names.
  • When multiple matches exist, an interactive grid menu appears for selection.

Dynamic Prompt

[OK]~/projects/42sh $> _
[KO]~/projects/42sh $> _   # red when last command failed
  • [OK] (green) or [KO] (red) reflects the exit status of the last command.
  • Current directory is shown relative to $HOME using ~ notation.

Variable & Backtick Expansion

echo $HOME
echo $?
echo `whoami`

Globbing

ls *.c
cat src/**/*.c

Project Structure

42sh/
├── main.c                    # Entry point
├── Makefile
├── include/
│   ├── my.h                  # All function prototypes
│   ├── struct_mysh.h         # All type / struct definitions
│   └── macros.h              # ANSI color macros
├── src/
│   ├── core/                 # Main shell loop (mysh.c)
│   ├── parsing/              # Lexer, AST builder, quote/inhibitor handling
│   ├── execution/            # AST executor, pipes, redirections, globbing
│   ├── builtins/             # cd, setenv, alias, which, where, repeat, set…
│   ├── environment/          # Env linked-list management, variable expansion
│   ├── history/              # History storage, navigation, event expansion
│   ├── completion/           # Tab-completion engine and menu
│   ├── alias/                # Alias tools
│   ├── termios/              # Raw-mode terminal enable/disable
│   └── bonus/                # Dynamic prompt, greeting screen
└── lib/
    └── my/                   # Custom libc reimplementations (my_strlen, etc.)

Testing

Unit tests use the Criterion testing framework.

# Run tests + coverage summary
make tests_run

# Generate an HTML coverage report
make coverage

Makefile Targets

Target Description
make Build libmy.a and 42sh binary
make clean Remove object files
make fclean Remove objects, binary, and library
make re Full rebuild (fclean + all)
make tests_run Compile and run unit tests with coverage
make coverage Generate HTML coverage report
make setup Configure git hooks
make help Display help menu

Authors

  • Mathis — Epitech TEK1 — 2025/2026
  • Loan — Epitech TEK1 — 2025/2026
  • Matthis — Epitech TEK1 — 2025/2026
  • Safwan — Epitech TEK1 — 2025/2026
  • Victor — Epitech TEK1 — 2025/2026

About

A fully-featured Unix shell written in C — piping, redirections, history, tab-completion, aliases, globbing & more. Epitech TEK1 project.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors