Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: THEend8_
1 Objective
Understanding how a shell works.
Increasing experience with system calls.
Learning about redirection and pipes.
Learning about job controls.
2 Introduction
This project will help you understand Unix shell and system calls. After completing the
project, you should be familiar with programming with LINUX system calls.
Essentially, a shell should prompt the user for input. The prompt usually consists of the
current directory. After the user inputs the command line, the shell parses it, and executes
each part of the command line according to the specification.
You should write a simple LINUX shell. The shell should read a line of input, process
it, and execute the commands. In particular, you are required to implement: (i) handling
built-in commands (which are to be handled by the shell itself) and external programs; (ii)
handling of important shell constructs (such are pipes, redirection, etc.); (iii) handing jobs
(such as put a foreground job to background and put a background job to foreground).
This is a group project. You can form a group with at most 3 members. You shall
learn how to solve a middle-level problem with collaboration with your partners and learn
how to manage your time under a tight schedule.
3 Specification
3.1 Introduction
The shell program that you are going to implement is a simpler version than the ones that
you use in Unix or Linux system. For simplicity, we name the shell that you are going to
implement as the OS shell.
1. When the OS shell first starts, the program should be in the state “Waiting for input
command line”. The OS shell should show the following prompt:
$ _
1
There should be one and only one white space after the dollar sign.
2. When the user types in a command followed by a carriage return (or the “enter” key),
e.g.,
$ ls | more
Then, the received input will be processed by the “Command line interpreter” of the
OS shell.
If the command line interpreter finds that the input command line agrees with the
pre-defined syntax, which will be defined in Section 3.2, then the OS shell should
invoke the commands specified by the input command line.
Else, the input command line will not be executed and the OS shell gives the error
messages to the user “Commands not found!”, and then waits for another input
command line, i.e., going back to the state “Waiting for input command line”.
3.2 Command line interpreter
The input command line is a character string. The OS shell should read in the input command
line from the standard input stream (stdin in C) of the OS shell. To ease your implementation,
there are assumptions imposed on the input command line:
Assumptions
1. An input command line has a maximum length of 80 characters.
2. An input command line ends with a carriage return character ‘\n’.
3. There is neither leading nor trailing space characters in the input command line.
4. A token is a series of characters without any space characters. Each token (or word) in
the input command line is separated by at least one space character.
3.2.1 Internal commands
The OS Shell should support the following internal commands:
Any other build-in commands, e.g., ls, mkdir, who, whoami, cp, mv, rm, rmdir, cal,
chmod, pwd, etc, where I do not list all the commands, which does not mean that the
OS shell cannot process them. In fact, the OS shell should support all the commands.
exit terminates your OS Shell.
go ARG changes the current working directory to the directory supplied as ARG, where ARG
cab be any valid directory. If there is no argument, you should print an error message.
pid displays the pids of the 5 recent child processes,
$ pid
2
history The OS shell can display all the historical commands that have been executed
before (the maximum history record is 5000).
Note that the OS shell should be able to resolve the parameters of these commands as
well. For example, ls –al.
3.2.2 External programs
The OS shell should be able to execute any other external programs as well. For example,
an executable program “hello” generated by gcc compiler can run in the OS shell correctly,
e.g., your run “./hello” in the OS shell.
3.3 Shell constructs (I/O Redirection and Pipes) and multiple commands
There are certain constructs the OS shell needs to support.
redirection - standard input is redirected using < ARG. This means that command receives
everything written in the file ARG, as it would be typed on the keyboard. Standard output is
redirected by using > ARG. You do not need to care about standard error.
pipes - two (or more) commands can be connected together using the syntax COMMAND1 |
COMMAND2. This connects the output of COMMAND1 to the input of COMMAND2.
Note:
For simplicity, the OS shell only need to support either input redirection or output
redirection and you do not need to consider them both at the same shell.
Similarly, you shell only need to support one pipe although you can implement multiple
pipes, which may lead to bonus points (please refer to Section 3.5).
Your OS shell support executing multiple commands in one line. For example,
$ mkdir ddd; ls > text.txt; mv text.txt ddd
In this way, a directory named “ddd” is firstly created following by a redirection “ls”
command to a file namely “text.txt. Finally, this file is moved to the created directory
“ddd”.
3.4 Job control
The OS shell need to support basic job controls of a Unix Shell.
Kill a job However, the user must be able to kill the current child processes by sending
it a SIGINT signal, typically by typing Ctrl-c. A SIGINT signal should not kill OS shellitself.
Suspend a job The user can type “Ctrl+z” to temporarily suspend a running frontground
command, the shell shall give the user some hints about the suspended command.
Specifically, the OS shell shall show the job number of the suspended command, e.g., “<JobNum>
Suspended” after users type command “jobs”.
Continue a job Then, the user can use the command “continue <JobNum>” to let the
suspended job continue to run, where “<JobNum>” is the job number assigned by the OS
shell.
List all the running jobs The user can type “jobs” to display all the current running
jobs in your system as well as the status of the jobs. For example,
3
[OS shell:/home/S171234]$ jobs
[1] Suspended
[2] Running
[3] Terminated
Put a foreground job to background the user can type “Ctrl+z” to temporarily
suspend a running front-ground command, the shell shall give the user some hints about
the suspended command. Specifically, the OS shell shall give the job number of the suspended
command, e.g., “<JobNum> Suspended”. Then, the user can use the command “bg
<JobNum>” to put the suspended job to background, where “<JobNum>” is the job number
assigned by the OS shell.
Put a background job to foreground the user can type “command &” to run a command
(job) in background (Note that this command shall run relatively a long time, e.g., “sleep
1000 &”). The OS shell shall also give a hint about the background job information (i.e., the
job number) so that the user can seize the control the job later. Before the background job
end, the user can put it to the foreground by using the command “fg <JobNum>” and then
the background shall run in foreground.
status this command should print the status of the last command executed. Commands
return 0 as the indication of success, and any non-zero value to indicate the failure.