This project involves creating a custom UNIX shell for an Operating Systems lab assignment. The shell simulates essential shell features, allowing users to execute commands, manage background processes, use input/output redirection, manage command history, and handle shell variables. Each version of the shell builds upon the previous, gradually adding more functionality until a fully functional shell environment is achieved.
-
Objective: Implement the foundational shell capabilities.
-
Features:
- Displays a custom prompt.
- Parses user input to execute basic commands.
- Uses
fork()
andexec()
to execute commands in a child process. - Allows the shell to exit using the
exit
command or<CTRL+D>
.
-
Usage:
- Run simple commands such as
ls
,pwd
,whoami
. - Exit by typing
exit
or pressing<CTRL+D>
.
- Run simple commands such as
-
Objective: Add input and output redirection.
-
Features:
- Supports output redirection using
>
. - Supports input redirection using
<
. - Allows combined input and output redirection, e.g.,
command < input.txt > output.txt
.
- Supports output redirection using
-
Usage:
- Redirect output:
ls > output.txt
(writes the output ofls
tooutput.txt
). - Redirect input:
sort < unsorted.txt
(reads fromunsorted.txt
). - Combined redirection:
sort < unsorted.txt > sorted.txt
(sorts contents ofunsorted.txt
and writes tosorted.txt
).
- Redirect output:
-
Objective: Implement background processing.
-
Features:
- Enables background process execution by appending
&
to commands. - Displays background job details (PID and job ID) when a job is started.
- Prevents "zombie" processes by handling background processes in a non-blocking way using
waitpid()
withWNOHANG
.
- Enables background process execution by appending
-
Usage:
- Start a background job:
sleep 30 &
(runssleep
in the background). - List background jobs:
jobs
. - Kill a background job:
kill <pid>
(replace<pid>
with the process ID).
- Start a background job:
-
Objective: Provide a command history feature.
-
Features:
- Tracks up to the last 10 commands.
- Displays command history using
history
. - Supports re-execution of a specific command from history by typing
!number
, wherenumber
is the command’s position in the history list.
-
Usage:
- View history:
history
(lists the last 10 commands). - Execute a previous command:
!1
(executes the first command from history).
- View history:
-
Objective: Implement core built-in commands without forking.
-
Features:
- Implements essential built-in commands:
cd
,jobs
,kill
, andhelp
.cd <directory>
: Changes the current directory.jobs
: Lists all active background jobs.kill <pid>
: Terminates a background process by its PID.help
: Displays available built-in commands and their usage.
- Implements essential built-in commands:
-
Usage:
- Change directory:
cd /tmp
(moves to/tmp
directory). - View background jobs:
jobs
. - Terminate a process:
kill <pid>
. - Get help:
help
.
- Change directory:
-
Objective: Add shell variable support for setting, retrieving, and unsetting variables.
-
Features:
- Enables users to define variables with
set <name>=<value>
. - Retrieves variable values by typing the variable name directly.
- Lists all defined shell variables using
printenv
. - Unsets (removes) a variable with
unset <name>
.
- Enables users to define variables with
-
Usage:
- Set a variable:
set myvar=hello
(creates a variablemyvar
with the valuehello
). - Access a variable:
myvar
(printshello
). - List all variables:
printenv
. - Unset a variable:
unset myvar
(removesmyvar
).
- Set a variable:
-
Compile the Code:
- Open a terminal in the directory containing your code file (e.g.,
shell.c
). - Compile the shell with:
gcc -o myshell shell.c
- Open a terminal in the directory containing your code file (e.g.,
-
Run the Shell:
- Start the shell by running:
./myshell
- Start the shell by running:
- Run commands such as
ls
,pwd
, andwhoami
to confirm basic execution. - Type
exit
or press<CTRL+D>
to exit the shell.
- Output redirection:
ls > output.txt
. Checkoutput.txt
for output. - Input redirection: Create
unsorted.txt
, then runsort < unsorted.txt
. - Combined redirection:
sort < unsorted.txt > sorted.txt
. Checksorted.txt
.
- Start a background job:
sleep 30 &
. - View active jobs with
jobs
. - Kill a job using
kill <pid>
, where<pid>
is fromjobs
.
- Run several commands (
ls
,pwd
,whoami
). - Type
history
to view the last 10 commands. - Use
!number
(e.g.,!1
) to repeat a command from history.
cd /tmp
to test changing directories.- Start a background job (
sleep 30 &
), then check withjobs
. - Terminate a job with
kill <pid>
fromjobs
. - Type
help
to view all built-in commands.
- Set a variable:
set myvar=hello
. - Access it by typing
myvar
(should outputhello
). - List all variables with
printenv
. - Unset
myvar
withunset myvar
and verify it no longer displays.
Here’s an example session showing the use of various features across all versions:
PUCITshell@/home/user:- ls
file1.txt file2.txt shell.c
PUCITshell@/home/user:- set myvar=hello
PUCITshell@/home/user:- myvar
hello
PUCITshell@/home/user:- pwd > output.txt
PUCITshell@/home/user:- sleep 30 &
[Background] Started process with PID 1234
PUCITshell@/home/user:- jobs
[1] PID: 1234
PUCITshell@/home/user:- kill 1234
Process 1234 terminated.
PUCITshell@/home/user:- history
1: ls
2: set myvar=hello
3: myvar
4: pwd > output.txt
5: sleep 30 &
6: jobs
PUCITshell@/home/user:- !1
file1.txt file2.txt shell.c
PUCITshell@/home/user:- help
Built-in Commands:
cd <directory> - Change directory
exit - Exit the shell
jobs - List background jobs
kill <pid> - Terminate background process with PID
history - Display command history
set <name>=<value> - Set a shell variable
unset <name> - Remove a shell variable
printenv - List shell variables
help - List built-in commands
PUCITshell@/home/user:- printenv
myvar=hello
PUCITshell@/home/user:- unset myvar
PUCITshell@/home/user:- myvar
Error executing command: No such file or directory
PUCITshell@/home/user:- exit
- Limited History: Only stores the last 10 commands.
- Limited Variables: Supports a maximum of 50 shell variables.
- Background Process Limit: Only allows 10 concurrent background processes.
This project emulates core functionalities of a UNIX shell, building progressively with each version:
- Basic command execution.
- I/O redirection.
- Background job control.
- Command history management.
- Built-in commands.
- Shell variable management.
Through this project, users gain a deep understanding of process control, input/output management, and command handling in a UNIX-like environment, which are crucial skills for systems programming and operating systems development.
Thanks to the Operating Systems Lab course for providing foundational concepts and guidance, and to online resources on fork()
, execvp()
, dup2()
, and signal handling for aiding the development of this shell.