This is a stripped-down shell implemented in C.
Kishmish supports the following features:
- Built-in commands:
ls [al]
,echo
,pwd
,cd
,quit
,history
,pinfo
,nightswatch
,setenv
,unsetenv
,jobs
,kjobs
,overkill
,fg
,bg
,cronjob
,quit
- Process management including foreground and background processes and switching between them.
- Piping and redirection
- Signal handling for signals like
SIGINT
andSIGTSTP
- A prompt that shows the username, hostname and the current working directory
- Command history and up arrow command recall across sessions
- Appropriate error handling
Kishmish does not support the following yet:
- Glob expansion and tab completion
- Support for quoting and escape sequences
- Aliasing
- User profiles
- Environment variables
and maybe a lot more...
In the directory where the source files reside, execute:
$ make
$ ./kishmish
To clean up object and binary files, execute:
$ make clean
shell.c
: Contains the REPL of the shellutils.c
: Contains several utility functions such as those for string processing,~
expansion, storing and retrieving session history, initialization and cleanupprompt.c
: Contains the function responsible for generating and printing the shell promptparse.c
: Contains functions that parse and sanitize the entered commands and call appropriate functionsexternal.c
: Contains functions that handle the execution of external programs in the foreground and backgroundexit.c
: Contains functions that implement thequit
commandpwd.c
: Contains functions that implement thepwd
commandcd.c
: Contains functions that implement thecd
commandls.c
: Contains functions that implement thels
commandecho.c
: Contains functions that implement theecho
commandpinfo.c
: Contains functions that implement thepinfo
commandhistory.c
: Contains functions that implement thehistory
commandnightswatch.c
: Contains functions that implement thenightswatch
commandbg.c
: Contains functions that implement thebg
commandcronjob.c
: Contains functions that implement thecronjob
commandenv.c
: Contains functions that implement thesetenv
andunsetenv
commandsfg.c
: Contains functions that implement thefg
commandjobs.c
: Contains functions that implement thejobs
commandkjob.c
: Contains functions that implement thekjob
commandoverkill.c
: Contains functions that implement theoverkill
commandpipe.c
: Contains function that help in parsing and setting up command pipelinesprocess.c
: Contains utility functions for process managementrecall.c
: Contains functions that implement up arrow command recallredirection.c
: Contains functions that implement input and output redirectionsignals.c
: Contains functions that handle signals sent to the shellmakefile
: Contains themake
rules for compiling the filesREADME.md
: The file you are reading nowREADME.pdf
: Another file you could be reading nowLICENSE
: This project is open-sourced under an MIT license. Details in this file. WARNING: Legal language ahead.
A header file accompanies each of the C files listed above
- Kishmish indicates that it is waiting for input by printing a prompt that shows the current username, hostname and working directory address.
- The working directory address is shown relative to the home directory, which is defined as the directory where the shell executable resides1.
- Kishmish accepts bash-like commands and is capable of executing a list of semi-colon-separated ones.
- Kishmish is capable of parsing space-separated arguments
- Kishmish tries to handle all reasonable input errors appropriately.
- Kishmish stores command history across sessions, capped at a maximum of 20 commands2.
- Command recall on pressing the Up arrow key is supported up to 20 commands3. Kishmish does not currently support editing the recalled command before execution.
- This is achieved by storing history data in a file at the end of this session and reading it at the beginning of the next. During a session, history data is managed internally in an array. This is to reduce the number of file accesses and improve performance.
- The history file,
.kishmish_history.dat
, is a binary file that is created automatically in the home directory, if it doesn't already exist. Deletion of this file is harmless, except the loss of history data from the previous sessions. - The history data is written to file only when the shell exits normally, that is on receiving an
EOF
signal (Ctrl+D on Linux-based systems) or upon use of thequit
command.
- Kishmish is capable of launching external programs in the foreground as well as in the background.
- This is achieved by forking the shell process into two, and replacing the child process's program image with that of the desired program.
- Depending on whether the program was invoked in the foreground or in the background, the parent process does or does not wait for the child process to terminate, respectively.
- Invocation in the background is requested by adding an ampersand symbol (
&
) after the complete command. It may or may not be separated by whitespace. Any part of the command after the&
symbol is ignored. - Kishmish prints an alert if a background job terminates.
- Kishmish supports switching jobs between foreground and background execution using the
fg
,bg
commands and theSIGTSTP
signal (Ctrl+Z) on Linux based systems. - This is achieved by maintaining an internal list of processes, managing processing groups and manipulating the foreground process group of the attached terminal.
- Kishmish supports input and output redirection using
<
,>
and>>
. - This is achieved by duplicating the file descriptors of the standard I/O files.
- Kishmish also supports pipelining of commands using
|
, achieved using thepipe
syscall.
- All built-in commands listed above behave as expected, mimicking the behaviour of bash.
- The syntax of some peculiar commands is elaborated below:
-
cronjob -c command -t wait -p time
: Repeatedly runcommand
after everywait
seconds for a total duration oftime
seconds in a subshell in the background. The subshell is however granted access to terminal I/O and runs in the same process group as Kishmish.
-
nightswatch -n wait [dirty | interrupt]
: This command prints certain system information to the screen everywait
seconds. The command runs in Kishmish itself, not in a separate subshell, hence it cannot be sent to the background and cannot be interrupted. This is by design, because the command needs to periodically print data to the terminal. It can be exited using the sequence Q+Enter. The information displayed corresponds to the amount of dirty memory in the system cache ifdirty
is selected, or the number of keyboard interrupts per CPU core ifinterrupt
is selected.
-
fg job-number
orbg job-number
where job number is the job number assigned by the shell, different from the process id
-
- for command recall, press the Up arrow the required number of times and press Enter
-
kjob job-number signal-number
sends signal withsignal-number
to process withjob-number
-
overkill
kills all background processes at once
-
pinfo [pid]
lists information about process withpid
as the process id. If no process id is specified, it lists information about Kishmish's own process
Have a grape day!
1: As per requirements
2: As per requirements
3: As per requirements