A minimal Unix shell implementation written in C, featuring command execution, pipes, redirections, and built-in commands.
Minishell is a lightweight shell that mimics the behavior of /bin/bash. It provides essential shell functionality including command parsing, execution, environment management, and I/O redirection.
- Command Execution: Execute external programs with proper PATH resolution
- Pipes (
|): Chain multiple commands together - Input/Output Redirections:
- Input redirection (
<) - Output redirection (
>) - Append redirection (
>>) - Here-documents (
<<)
- Input redirection (
- Environment Variable Expansion: Support for
$VARIABLEand$?(exit status) - Quote Handling: Proper parsing of single and double quotes
- Signal Handling: Handles SIGINT (Ctrl+C) and SIGQUIT (Ctrl+)
echo: Print text with optional-nflagcd: Change directory with proper PATH handlingpwd: Print working directoryexport: Set environment variablesunset: Remove environment variablesenv: Display environment variablesexit: Exit the shell with optional exit code
- GCC or Clang compiler
- readline library: For command-line editing and history
- Make: For building the project
- Unix-like system: Linux, macOS, or WSL
brew install readlinesudo apt-get install libreadline-dev build-essentialmake # Compile the shell
make clean # Remove object files
make fclean # Remove all compiled files and executable./minishell# Execute external commands
ls -la
pwd
echo "Hello, World!"
# Use pipes
cat file.txt | grep "pattern" | wc -l
# Redirections
echo "Hello" > output.txt
cat < input.txt > output.txt
echo "Appending" >> file.txt
# Here-documents
cat << EOF
This is a here-document
EOF
# Environment variables
export MY_VAR="value"
echo $MY_VAR
unset MY_VAR
# Change directory
cd /path/to/directory
cd ..
cd ~
# Exit code
echo $?Print text to standard output.
echo "Hello" # Print text
echo -n "No newline" # Without trailing newlineChange the working directory.
cd /home/user
cd ..
cd ~
cd -Print the current working directory.
pwdSet environment variables.
export VAR_NAME="value"
export PATH=$PATH:/new/pathRemove environment variables.
unset VAR_NAMEDisplay all environment variables.
envExit the shell.
exit
exit 42Clear the terminal screen.
clearThe shell parses user input into tokens and constructs a command structure that supports:
- Simple commands
- Pipes connecting multiple commands
- Input/output redirections
- Command chaining
Variable expansion is performed at parse time:
$VARIABLE: Expands to environment variable value$?: Expands to the exit status of the last command- Quote handling prevents expansion within single quotes
Commands are executed in child processes using fork() and execve(), maintaining the parent shell process for subsequent commands.
User Input
↓
Tokenization & Parsing
↓
Variable Expansion
↓
Quote Removal
↓
Redirection Setup
↓
Command Execution
↓
Output
- No job control (background processes are not fully supported)
- Limited wildcard expansion
- No command history search
- No aliases
- Simplified regex handling
The shell returns the exit code of the last executed command:
0: Success1-127: Command-specific error128+N: Command terminated by signal N127: Command not found126: Command not executable