Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Write a C shell program that will read lines of text, break each line into tokens, and execute the command indicated by the first token.

Write a C shell program that will read lines of text, break each line into tokens, and execute the command indicated by the first token.

BACKGROUND CONTEXT: For example:

ls -al ~home/bin 

is a command with three tokens ("ls", "-al" and "~home/bin"). The shell works out where the executable for the ls command is located, and executes it, passing the second two tokens as command-line arguments.

However, shells do a lot more than just reading command lines and executing them. For example, they keep a history of previous commands to make it easy to re-execute them. They also allow users to capture the output of a command, by redirecting its output into a file. And, importantly on Unix/Linux, they allow users to build a pipeline of commands to achieve powerful effects without having to write a program. For example, the following pipeline produces a list of the top ten most frequently used words in a text file:

cat blah.txt | tr -cs '[a-z]' ' ' | sort | uniq -c | sort -nr | head -10 

The shell needs to be able to do the following:

Read and execute commands (1 mark)

The shell should print a prompt using the supplied prompt() function. It then reads a single line of text and interprets it as a command. A command is a sequence of space-separated tokens on a single line. The first token is treated as the name of a command, where the command exists as an executable file somewhere in the user's PATH. If no such executable is found, the shell should print a "Command not found" message.

The command is invoked via the execve() library function, with the full pathname of the command as the first parameter, the sequence of tokens as the second parameter, and the user's environment (from the third argument of the the main program) as the third parameter.

Maintain a history of the previous 20 valid commands (2 marks)

The shell should maintain a persistent list of the most recent 20 valid commands that the shell has executed. Each command is associated with a sequence number; sequence numbers increase constantly over time, and persist between sessions with the shell

Implement shell built-in commands (1 mark)

The following commands are handled by the shell, and do not need to be searched for in the command path.

exit

terminate the shell (after saving the command history)

h or history

display the last 20 commands, with their sequence numbers

pwd

print the shell's current working directory (hint: getcwd())

cd Directory

change the shell's working directory (after filename expansion) after changing, show the new working directory (hint: chdir() and getcwd())

The exit built-in is not placed in the command history.

Expand filename wildcards (2 marks)

If any of the following characters ('*', '?', '[', '~') appears in one of the tokens, that token should be replaced by all of the tokens matching that token using the glob() library function. This may result in the tokens list becoming longer than initially. If there are no matches, use the token unchanged. (hint: use GLOB_NOCHECK|GLOB_TILDE as the second parameter of the glob() function)

Redirect command input (2 marks)

If the command line contains the tokens < and a filename as the last two tokens, the command should be executed with its standard input connected to the named file. If the file does not exist, or is not readable, that is an error. Having < as the last token, or elsewhere in the command-line is also an error. (Hint: pipe() and dup2())

Redirect command output (1 mark)

If the command line contains the tokens > and a filename as the last two tokens, the command should be executed with its standard output connected to the named file. If the file does not already exist or exists and is writeable, then it is truncated to zero length and it current contents are overwritten. If the file exists and is not writeable, that is an error. Having > as the last token, or elsewhere in the command-line is also an error. (Hint: pipe() and dup2())

PSEUDOCODE: The main function should be structured roughly as follows:

main() { restore the command history print prompt while (more commands) { if empty command, ignore handle ! history substitution tokenise handle *?[~ filename expansion handle shell built-ins check for input/output redirections find executable using first token if none, then Command not found sort out any redirections run the command print prompt } save command history }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Excel As Your Database

Authors: Paul Cornell

1st Edition

1590597516, 978-1590597514

More Books

Students also viewed these Databases questions