Mumsh
A mini shell supporting tab-triggered hint & auto-completion written in C
Install / Use
/learn @kx-Huang/MumshREADME
mumsh: A Mini Shell Written in C
</div>

Documentation 
This project is originated from a course project in VE482 Operating System @UM-SJTU Joint Institute. In general, a mini shell called mumsh is implemented with programming language C for Unix-like machine.
Change Log 
For VE482 course project version, see Releases: VE482 Project 1 or Branches: VE482.
-
[2022/2/19] Add feature: Command history auto-completion with smart search
-
[2022/2/15] Add feature: Tab-triggered hint and auto-completion
-
[2022/2/13] Add feature: Left & right cursor switch and dynamic insert & delete
-
[2022/2/12] Add feature: Dynamic current path prompt in prefix
-
Future upgrade list:
- Handle print overflow regarding terminal size
CTRL-Dkeyboard capture and interruption- Show
Gitstatus in prefix - Auto translate
~to home path in parser
Functionalities
mumsh supports some basic shell functionalities including:
- Tab-triggered hint and auto-completion
- Command history auto-completion with smart search
- Incomplete input waiting
- Syntax error handling
- Quotation mark parsing
- Internal commands
exit/pwd/cd/jobs - I/O redirection under
bashstyle syntax - Arbitrarily-deep pipes running in parallel
CTRL-Cinterruption- Background jobs
In this README, the following content will be included:
- What files are related to
mumsh - How to build and run
mumsh - How to play with
mumsh - How to implement
mumsh
0. Files related to mumsh
We have 4 kinds of files in this project:
- README
- It's strongly adviced to read
README.mdbefore runningmumshor reading source code, since it may give us more sense of whatmumshis doing in each stage.
- It's strongly adviced to read
- C Source files: (in executing order)
mumsh.c: where main read/parse/execute loop ofmumshlocatesio.c: handle reading command line input ofmumshhinter.c: input interface with tab-triggered hint and auto-completionparser.c: parse user input into formatted commands for coming executionprocess.c: execute commands in child process according to specifications
- C header files: (hierarchy from top to bottom)
mumsh.hio.hhinter.hparser.hprocess.h: store global variables regarding processdata.h: store extern global variables regarding read/parse/execute loop
- makefile
- used for quick build and clean of executable files
1. Build and Run mumsh
mumsh is only available on Unix-like machine, as some libraries are not avaiable in Windows.
- build:
$ make - run:
$ ./mumsh
If everything is normal, we can see in the terminal mumsh $ , which indicates that mumsh is up and running, waiting for our input.
2. Play with mumsh
Once mumsh is up and running, we can start inputting some commands such as ls or pwd to test the basic functionalities if you have already been familiar to shell.
Of course, mumsh is only a product of a course project supporting basic functions, and yet to be improved. For its detailed ability, please check the following sections.
2.1 Overall mumsh Grammar in Backus-Naur Form
cmd [argv]* [| cmd [argv]* ]* [[> filename][< filename][>> filename]]* [&]
Seems abstract and maybe get a little bit confused? Let me explain a little more.
The input of mumsh can be made up of 4 components:
- command and argument:
cmd,argv - redirector and filename:
<,>,>>,filename - pipe indicator:
| - background job indicator:
&
2.1.1 Command and Argument
cmdis a must, ormumshwill raiseerror: missing programargvis optional, we can choose to call a command with arguments or not.
2.1.2 Redirector and Filename
<,>,>>is optional, but we should input redirector along with filename- if any
<, >, |, &instead offilenamefollows,mumshwill raiseerror: syntax error near unexpected token ... - if no character follows,
mumshwill prompt us to keep input in newline
- if any
>and>>can't exist in the same command, ormumshwill raiseerror: duplicated output redirection
2.1.3 Pipe Indicator
|is optional, but we should input|after one command and followed by another command- if no command before
|,mumshwill raiseerror: missing program - if no character after
|,mumshwill prompt us to keep input in newline
- if no command before
|is incompatible with having>or>>before it, and having<after it- if
>or>>comes before|,mumshwill raiseerror: duplicated output redirection - if
<comes after|,mumshwill raiseerror: duplicated input redirection
- if
2.1.4 Background Job Indicator
&is optional, but we should only input&at the end of input, ormumshwill ignore the character(s) after&is detected.
Now, we have our components of input to play with, and we can try it out in mumsh by assembling them into a whole input. As long as mumsh doesn't raise an error, our input syntax is valid, even though this input may give no output.
2.2 Simple Commands
mumshbuilt-in commandsexit: exitmumshpwd: print working directorycd: change working directoryjobs: print background jobs status
- executable commands (call other programs to do certain jobs)
ls: call program/bin/ls, which print files in current working directorybash: call shell/bin/bash, which is also a shell likemumshbut with more powerful capabilities- we can input
ls /binto see more executable commands
2.3 I/0 Redirection (support bash style syntax)
-
Input redirection
< filename: read from file namedfilename, or raise error if nofilenameexists
-
Output redirection
> filename: overwrite if file namedfilenameexists or create new file namedfilename>> filename: append if file namedfilenameexists or create new file namedfilename
-
support bash style syntax
- An arbitrary amount of space can exist between redirection symbols and arguments, starting from zero.
- The redirection symbol can take place anywhere in the command.
- for example:
<1.txt>3.txt cat 2.txt 4.txt
2.4 Pipe
- takes output of one command as input of another command
- basic pipe syntax:
echo 123 | grep 1
- basic pipe syntax:
mumshsupport parallel execution: all piped commands run in parallel- for example:
sleep 1 | sleep 1 | sleep 1only takes 1 second to finish instead of 3 seconds
- for example:
mumshsupport arbitrarily deep “cascade pipes”- for example:
echo hello world | grep h | grep h | ... | grep h
- for example:
2.5 CTRL-C
-
interrupt all executing commands in foreground with
CTRL-C -
cases:
-
clear user input and prompt new line
mumsh $ echo ^C mumsh $ -
interrupt single executing command
mumsh $ sleep 10 ^C mumsh $ -
interrupt multiple executing commands
mumsh $ sleep 10 | sleep 10 | sleep 10 ^C mumsh $ -
CTRL-C don't interrupt background jobs
mumsh $ sleep 10 & [1] sleep 10 & mumsh $ ^C mumsh $ jobs [1] running sleep 10 & mumsh $
-
2.6 CTRL-D
-
if
mumshhas no user input,CTRL-Dwill exitmumshmumsh $ exit $ -
if
mumshhas user input, do nothingmumsh $ echo ^D
2.7 Quotes
-
mumshtakes any character between"or'as ordinary character without special meaning.mumsh $ echo hello "| grep 'h' > 1.txt" hello | grep 'h' > 1.txt mumsh $
2.8 Background Jobs
-
If
&is added at the end of user input,mumshwill run jobs in background instead of waiting for execution to be done. -
Command
jobscan keep track on every background jobs, no matter a job isdoneorrunning -
mumshsupportpipein background jobsmumsh $ sleep 10 & [1] sleep 10 & mumsh $ sleep 1 | sleep 1 | sleep 1 & [2] sleep 1 | sleep 1 | sleep 1 & mumsh $ jobs [1] running sleep 10 & [2] done sleep 1 | sleep 1 | sleep 1 & mumsh $ -
mumshsupport command formattingmumsh $ <'i'n c"a"t| cat |ech'o' "he"llo>out world!& [1] cat < in | cat | echo hello world! > out & mumsh $ jobs [1] done cat < in | cat | echo hello world! > out & mumsh $
3. Implement mumsh Step by Step
In this section, we will go through the construction of mumsh step by step, giving us a general concept of how this shell work. This section is intended for helping beginners (just as me a week ago) grab some basic concept for implementing a shell.
However, some contents such as detailed data structure and marginal logic will be neglected. And the demo code is used for our better understanding instead of doing copy and paste. As a result, the grammar is not strictly follow the C standard. For more detail, we can read the source code directly. It's strongly recommended to understand the concept before doing any coding.
3.1 Main Read/Parse/Execute Loop
As we all know, a shell is a computer program which exposes an operating system's services to a human user or other program. It repeatedly takes commands from the keyboard, gives them to the operating system to perform and
