A tiny Unix shell written in C, inspired by bash and built as part of the 42 cursus.
The goal: travel back in time and talk to your computer through a simple, interactive command line.
- Prompt that waits for a new command
- Command history (powered by
readline) - PATH resolution for executables, plus support for:
- Absolute paths (
/bin/ls) - Relative paths (
./my_script.sh)
- Absolute paths (
- Single global variable used only for signal handling
- Proper handling of quotes:
- Single quotes
'...'keep everything literal - Double quotes
"..."expand$VARbut keep other meta-characters
- Single quotes
- Redirections:
<— redirect input>— redirect output (truncate)>>— redirect output (append)<<— heredoc until a given delimiter (no history update)
- Pipes:
cmd1 | cmd2 | cmd3 - Environment variables:
$VARexpansion$?for the last exit status
- Logical operators and precedence:
&&and||- Parentheses for priority:
(cmd1 && cmd2) || cmd3
- Signal handling (interactive mode):
Ctrl-Cprints a new prompt on a new lineCtrl-Dexits the shellCtrl-\is ignored, like inbash
- No unrequired special characters: no interpretation of unclosed quotes,
\,;, etc.
Implemented built-ins (without extra options/flags unless specified):
echo [-n]– print text with optional no-newlinecd [path]– change directory (relative or absolute)pwd– print current working directoryexport– print environment (and manage exported variables internally)unset– remove environment variablesenv– print current environmentexit– exit minishell
- Language: C
- Build system: Makefile
- Targets:
all,clean,fclean,re
- Targets:
- Allowed external functions (as per subject):
readline,add_history,rl_clear_history,rl_on_new_line,rl_replace_line,rl_redisplayprintf,malloc,free,writeaccess,open,read,closefork,wait,waitpid,wait3,wait4signal,sigaction,sigemptyset,sigaddset,killexitgetcwd,chdirstat,lstat,fstat,unlinkexecve,dup,dup2,pipeopendir,readdir,closedirstrerror,perrorisatty,ttyname,ttyslot,ioctlgetenvtcsetattr,tcgetattrtgetent,tgetflag,tgetnum,tgetstr,tgoto,tputs
- Libft: allowed and used
- Memory: no leaks allowed in my code (the known
readlineleaks are tolerated by the subject)
gccorclangmakereadlinedevelopment headers installed
(e.g. on macOS:brew install readline, on Linux:sudo apt install libreadline-dev)
bash
make
This will compile the project and create the minishell executable.
To clean object files:
make clean
To clean everything (including the executable):
make fclean
To rebuild from scratch:
make re
Launch:
./minishell
You’ll see a prompt like:
minishell$
Basic examples:
minishell$ ls -la
minishell$ ls | grep .c | wc -l
minishell$ cat < input.txt
minishell$ echo "hello" > out.txt
minishell$ echo "another line" >> out.txt
minishell$ cat << EOF
type anything here
until this line:
EOF
minishell$ echo $HOME
minishell$ echo $?
minishell$ mkdir test && cd test
minishell$ false || echo "this runs"
minishell$ (false && echo nope) || echo "this runs instead"
Exit options:
Ctrl-D on an empty line
exit