42shell is a project in the Codam curriculum requiring you to build a shell with all basic functionality, plus a choice of six extra features.
The seven extra features we have built are:
- Complete management of quoting ✓
- Tab completion for built-ins, command, and files in current directory ✓
- Hash table for executables ✓
- test builtin ✓
- Arithmetic expansion using
$(())✓ - Command substitution using
$()✓ - Process substitution using
<()and>()✓ (BONUS)
Anything labeled with (BONUS) is not required by the project subject.
You can download a pre-compiled binary for Arch, Debian or Ubuntu if you trust our CI build jobs:
[DIRECT DOWNLOAD LINKS]
Compilation has been tested on MacOS Mojave, Debian, Ubuntu, and Arch linux, and requires the following dependencies:
To compile the shell, run the following commands:
$> meson build
$> cd build
$> ninja
The compiled executable will be called ./cetushell.
Optionally, you can install Criterion and run ninja test to compile and run a limited set of tests.
To start the shell, run ./cetushell.
42shell will initialize a minimal environment if it receives an empty environment.
This shell currently has the following features:
- Command execution based on
PATH - Hashing of executable names in hashtable, with corresponding
hashbuiltin - Non-interactive mode through redirection of input OR a file as argument (BONUS)
- Support for comments using
#. Aything after a#until the next newline is ignored. (BONUS) - Internal shell + environment variables, including assignment through assignment words, expansion (using
$KEYor${KEY}) and support for read-only - Changing the shell prompt by modifying the shell variable
PS1 - Pipes (including completion of pipes(BONUS))
- Redirections (>, <, >>, <<, >&, <&)
- Command history using
arrow upandarrow down(using$HISTFILE&$HISTSIZE, supports newlines(BONUS)) - Contextual
tabcompletion with support for files, directories, executables, and shell/environment variables. - Arithmetic expansion using
$((expr)), with support for variables and nesting with$((40 + $((2))))and decimal, hex, and octal numbers. - Command substitution using
$(command), with full support for anything supported in non-interactive mode. - Process substitution using
>(command)to redirect to the process or<(command)to redirect from the command. - Quotes (
",'and\), including in heredocs and the heredoc end word (i.e.EOF) - The operators
&&and||to chain multiple complete commands - Job control including the required builtins (see below) and
job_specwhich supports these formats:%-: matches previous job%+: matches current job%nmatches job with job idn%string: matches any job that begins withstring%?string: matchs any job that containsstring
- Command line control:
arrow keysto move left and right,ctrl + arrow keysto move per word or line- shift + arrow keys left and right to select
ctrl+bto copy,ctrl+xto cut,ctrl+vto paste.
cd [-P|-L|'-'] [PATH]: change directory toPATH, or home ifPATHis not iven.-Pwill update$PWDto absolute path ifPATHcontained symlinks-Lwill update$PWDto relative path ifPATHcontained symlinks default)-changes to previous directory (stored in$OLDPWD)
echo: supports-n(BONUS) to ommit trailing newlinehash [-r|-i|COMMAND[=PATH]]: manage the command hash tablejobs [-p|-l] [job_spec ...]: print status of jobs.-ponly prints the pgid of the job.-lalways print long output with details per process
fg [job_spec]: but job in foreground. ifjob_specis ommited,%+is assumed.bg [job_spec ...]: but all given jobs in foreground. ifjob_specis ommited, %+` is assumed.set: print all variables (shell and environment)unset [KEY ...]: unset all instances of everyKEYin shell and environment ariablesexport [-p|KEY[=VALUE] ...]: export everyKEYfrom the shell to the nvironment, or add it th the environment withVALUEif specified.-pwill print all environment variables in a valid format to export all of hem.
setenv: see--helpfor options and syntax (BONUS)unsetenv: see--helpfor options and syntax (BONUS)setshell: see--helpfor options and syntax (BONUS)unsetshell: see--helpfor options and syntax (BONUS)exit [exit_code]: exit the shell. exit code will beexit_codeif given, or ost recent status code. ($?)type [COMMAND ...]: prints type/location of everyCOMMAND.testwith support for[ expr ](BONUS) and!, and the following operators:-a: True if file exists. (BONUS)-b: True if file exists and is a block special file.-c: True if file exists and is a character special file.-d: True if file exists and is a directory.-e: True if file exists.-f: True if file exists and is a regular file.-g: True if file exists and its set-group-id bit is set.-h: True if file exists and is a symbolic link. (BONUS)-L: True if file exists and is a symbolic link.-p: True if file exists and is a named pipe (FIFO).-r: True if file exists and is readable.-S: True if file exists and is a socket.-s: True if file exists and has a size greater than zero.-u: True if file exists and its set-user-id bit is set.-w: True if file exists and is writable.-x: True if file exists and is executable.-z: True if the length of string is zero.-n: True if the length of string is non-zero. (BONUS) str1 OP str2: Arg1 and arg2 are strings, where OP can be:=: True if the strings are equal.==: True if the strings are equal. (BONUS)!=: True if the strings are not equal. int1 OP int2: Arg1 and arg2 may be positive or negative integers, where OP can e:-eq: True if arg1 is equal to arg2.-ne: True if arg1 is not equal to arg2.-gt: True if arg1 is greater than arg2. (BONUS)-ge: True if arg1 is greater than or equal to arg2.-lt: True if arg1 is less than arg2.-le: True if arg1 is less than or equal to arg2.