Skip to content

tristan-oa/Linux-Shell-in-C

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Eggshell: A Linux Shell Written in C

The C programming language was used to develop a Linux shell. This project was a programming assignment for the CPS1012: Operating Systems and Systems Programming 1 course, a course forming part of my B.Sc. in Computer Science.

The Eggshell Interpreter

Eggshell is a command-line interpreter for the Linux OS. It was designed to cater for the following:

  1. Shell Variables
  2. Internal and External Commands
  3. Input and Output Redirection
  4. Piping
  5. Process Management

These will be explained in the sub-sections to follow.


Shell Variables

Shell variables are character strings to which a value is assigned. Shell variable names should be in UPPERCASE and can contain any of the following:

  • letters ( A-Z )
  • numbers ( 0-9 )
  • underscores ( _ )

Eggshell was designed to cater for these shell variables by default:

PATH - The search path used to launch external commands

PROMPT - The string presented to the user to show that the shell is ready to accept command input

CWD - The path of the current working directory to which all file operations are relative to

USER - The current user's username

HOME - The current user's home directory

SHELL - The current user's shell

TERMINAL - The name of the terminal executing the current Eggshell session

EXITCODE - The exit code returned by the last program run by the shell

An assignment statement is used to modify existing shell variables or create new ones.

A shell variable's value is obtained by prefixing its name with a $. If a valid name is detected, the shell obtains its value from the list of shell variables.

> NEW_VAR=#
> print $NEW_VAR
#
> PROMPT=$NEW_VAR
# print The prompt has been changed to: $PROMPT
The prompt has been changed to: #

Internal and External Commands

Eggshell's command-line interpreter recognises a number of internal (built-in) and external commands.

When a new command is entered, it is compared to a list of built-in commands. If a command is not recognised as such, the shell treats the input as a call to an external command.

Internal Commands

Eggshell was designed to cater for the following internal commands:

exit - Terminates all running processes spawned by the Eggshell instance and quits the program

print - Echoes text expressions or variable values to standard output

chdir - Changes the current working directory (CWD)

all - Prints all the shell variables in key-value pairs

source - Provides scripting functionality. This command takes the name of a script file as its only argument and proceeds to open this file and execute all of its commands. Each executed command behaves exactly in the same way as if it were typed in

Eggshell's current implementation traps and handles errors when commands fail. It returns appropriate error messages indicating the reason for failure.

External Commands

The shell considers commands not included in the list above as external commands. It searches for matching program binaries through the system search path (PATH) and launches them as separate processes by forking.


Input and Output Redirection

Eggshell supports the following redirection operators:

> - Redirects a command's output into a file

>> - Redirects a command's output into a file, appending to the file's existing contents

< - Uses a file's contents as input to a command

<<< - Uses text as here string input to a command

The usage of these commands is shown in the examples below, where 'cmd' denotes an arbitrary command (internal/external) with zero or more arguments and 'f.txt' refers to an arbitrary file.

# cmd > f.txt
# cmd >> f.txt
# cmd < f.txt
# cmd <<< 'text
more text
even more text'

Piping

The Unix piping operator '|' was implemented to chain multiple processes by their input and output streams. This allows the output (stdout) of one process to feed directly into the input (stdin) of the next, and so forth.

As an example, consider the 4 command sequence below:

cat m.txt | grep a | wc -l | figlet > finish.txt

The output of one command is passed as input to the next, as if the commands are connected together as one whole process. The diagram below helps to visualise this concept.

The piping process for 4 commands
The piping process for 4 commands


Process Management

Shells reserve a keyboard shortcut (typically CTRL + C) to interrupt running processes. Given that Eggshell is a process itself, this shortcut would also terminate the current Eggshell instance.

To prevent this, the SIG INT signal triggered with this shortcut is trapped and forwarded to any process spawned by Eggshell, forcing this process only to exit, and not Eggshell itself.

Documentation

A detailed description of this project's deliverables can be found here.

A detailed technical documentation of the source code written can be found here.