The objective of this project is to create a simple shell, like an own little bash.
It is the first group project in the 42 core curriculum. (tjensen42 && hepple42)
For the project we were allowed to use GNU's readline library which handles the terminal interaction (history & input reading). For everything else the subject allows only to use a few low-level functions and a few POSIX system calls.
Allowed functions:
readline, rl_clear_history, rl_on_new_line,rl_replace_line, rl_redisplay, add_history, printf, malloc, free, write, access, open, read,close, fork, wait, waitpid, wait3, wait4, signal, sigaction, sigemptyset, sigaddset, kill, exit, getcwd, chdir, stat, lstat, fstat, unlink, execve, dup, dup2, pipe, opendir, readdir, closedir, strerror, perror, isatty, ttyname, ttyslot, ioctl, getenv, tcsetattr, tcgetattr, tgetent, tgetflag, tgetnum, tgetstr, tgoto, tputs
- History of previous entered commands
- Search and launch the right executable (based on the PATH variable, using a relative or an absolute path)
- Environment variables ($ followed by a sequence of characters) expand to their values
- Wildcards * in the current working directory
- ctrl-C, ctrl-D and ctrl-\ behave like in bash
’
(single quotes - prevent from interpreting meta-characters in quoted sequence)"
(double quotes - prevent from interpreting meta-characters in quoted sequence except for $)$?
expands to the last exit status|
connect cmds or groups with pipes; output of a cmd is connected to the input of the next cmd via a pipe&&
and||
with parenthesis for priorities
echo
with option -ncd
(relative or absolute path,-
for OLDPWD, without arg for HOME)pwd
without optionsexport
without optionsunset
without optionsenv
without optionsexit [exit_status]
without options
[n]
(optional) specifies the file descriptor, if not specified it is stdout/stdin
[n]< file
Redirecting Input[n]<< limiter
Here Documents[n]> file
Redirecting Output[n]>> file
Appending Redirected Output
The current version of minishell is developed and tested on macOS, but it should work on all UNIX/LINUX based systems as well.
Requirements:
- GCC / CLANG Compiler
- GNU Make
- GNU Readline library
git clone https://github.com/tjensen42/42-minishell.git minishell
cd minishell && make release
./minishell
Install readline with brew
brew install readline
brew link --force readline
Add the path to the lib
Replace ~/.zshrc with ~/.bashrc if you use bash instead of zsh
echo 'export C_INCLUDE_PATH="/usr/local/opt/readline/include:$C_INCLUDE_PATH"' >> ~/.zshrc
echo 'export LIBRARY_PATH="/usr/local/opt/readline/lib:$LIBRARY_PATH"' >> ~/.zshrc
source ~/.zshrc
Install Brew, only if it is not already installed:
rm -rf $HOME/.brew && git clone --depth=1 https://github.com/Homebrew/brew $HOME/.brew && echo 'export PATH=$HOME/.brew/bin:$PATH' >> $HOME/.zshrc && source $HOME/.zshrc && brew update
Install Readline library:
brew install readline
brew link --force readline
echo 'export C_INCLUDE_PATH="$HOME/.brew/include:$C_INCLUDE_PATH"' >> ~/.zshrc
echo 'export LIBRARY_PATH="$HOME/.brew/lib:$LIBRARY_PATH"' >> ~/.zshrc
source ~/.zshrc
To check if your minishell build was succesful you can run a tester, which compares most of the features with your current Bash installation. The test compares the stdout and the exit-code directly and checks in case of an error if both print something in stderr.
make test
Enter minishell and export the DEBUG env:
export DEBUG=printer
For all next commands you will execute in the minishell you will see the different processing steps from the lexer and parser with syntax highlighting.
- Enter the SHELL
./minishell
- Export the PS1 env (also works in Bash and other similar shells)
export PS1='enter your prompt wish...$ '
*All 42 projects must be written in C (later C++) in accordance to the 42 School Norm.
- All variables have to be declared and aligned at the top of each function
- Each function can not have more then 25 lines
- Projects should be created with allowed std functions otherwise it is cheating