The goal of this project is to make your own shell program. In order to construc
ID: 3853493 • Letter: T
Question
The goal of this project is to make your own shell program.
In order to construct your own shell, you have to construct
(a) command line interpreter, and
(b) commands itself, e.g. cat, chmod, etc.
The command line interpreter (as shown in Figure 1) is a basically a program waiting for a user input. Once user type a command with command line argument(s), it needs to parse it, understand it, and pass it to a proper function, which is an implementation of the particular command.
For instance, if you type “cat hello.cpp”, then the command line prompt understands the command “cat” with the argument “hello.cpp”. Then, it calls a function which is an implementation of cat with the string “hello.cpp” as its input argument.
For the project, you can use the system calls and the standard library functions from original C, but not from C++. That is, you can use only those listed in https://en.wikipedia.org/wiki/C_standard_library
and
the system calls discussed in the class. Still, you can use .cpp file extension to use c++ syntax.
Project Phase 1
You are required to submit three files, myshell.cpp, mycommands.h, and mycommands.cpp to d2l. myshell.cpp is your implementation of the command line interpreter. mycommands.h and mycommnds.cpp are the implementation of your commands. You are not allowed to use any existing program by exploiting any “exec”-family system calls. However, you are allowed to use any C/C++ standard library function. Below is the list of required implementations and corresponding grading policy.
(a) Command line interpreter
You are required to implement a command line interpreter, which will wait for a user input. Once input is given (i) it should list the command name, e.g. cat, and the arguments if any on the screen. Then, it should pass to the proper function in mycommands.h. (ii) Once the user type “exit”, then the interpreter ends.
(b) Commands
You must interpret the command line interpreter before starting this section. Otherwise, no point will be granted from this section. (does not include the extra credit portion)
Below is the list of commands to implement. The bottom line is that the way how implementations work should be identical to the way they are in bash shell to earn the point. (no partial credit!)
Command: cat
cat filename will print out all of the contents of the file on the screen if the file exists. Otherwise, it will print “cat: file-name-here: No such file or directory” on the screen.
Command: cp
cp file1 file2 is a command to create a new file namely file2, which is identical to file1. If file2 already exists, it will overwrite.
Command: ls
Command ls will print out the information of all files on the current working directory. Type “ls” to see what have to be printed.
Command: grep
Command grep looks for the text in files. It will list out the lines containing the text with filename if more than one file examined.
Explanation / Answer
bin/bash
#
# File: array.sh
#
# Description: simple array manipulation: create an array, get its length and the
# iterate through the array and print out each element
#
# Input: None
#
# Output: prints out each element of the array and its position.
#
# If you replace array with one of the lines below you will see the strength
# of backquoting a command into an array.
#array=(‘cat array.sh‘)
#array=(‘find‘)
#array=(‘ls‘)
array=(red green blue yellow black white)
len=${#array[*]}
echo "The array has length $len members. They are:"
i=0
while [ $i -lt $len ]; do
echo "$i: ${array[$i]}"
let i++
done
exit 0
Make sure you re-run the script with the other array definitions - this will help with the assignment.
Another example. You can executes this interactively and play with arrays. If you need to store information and update it while your script is running then arrays are good for this:
[campbell@moose ~]$ FILES=("Andrew" "Mirco" "Wei")
[campbell@moose ~]$ echo "${FILES[0]}"
Andrew
[campbell@moose ~]$ echo "${FILES[1]}"
Mirco
[campbell@moose ~]$ echo "${FILES[2]}"
#!/bin/bash
#
# File: guessprime.sh
#
# Description: The user tries to guess a prime between 1-100
# This is not a good program. There is no check on what the
# user enters, may not be a prime, might be outside the range.
# Some defensive programming would check the input against the bounds.
#
# Input: The user guesses a prime and enters it
#
# Output: Status of the guess
# Program defines a variable called prime and sets it to a value.
prime=31
echo -n "Enter a prime between 1-100: "
read guess
while [ $guess != $prime ]; do
echo "Wrong! try again"
echo -n "Enter a prime between 1-100: "
read guess
done
exit 0
Script source: shift.sh
#!/bin/bash
#
# Folks I wrote this to show the difference between the
# manipulation of $arg which loads the scripts input
# parameters in; a variable being incremented i,
# and finally using $1 and shift as a combo to
# walk through the input arguments to the script
# Here is an example of running the script with input:
#
#$ ./shift.sh one two three four
#
#
# First let’s print the scripts environmental variables:
echo $0 is the name of the script
echo $# is the number of parameters entered by the user
echo $$ is the process ID
echo $@ is the list of parameters entered
# Here is the input:
#
#tc@dhcp-210-177 spring_web]$ ./test.sh one two three four
#
# and the output
#
#This is the arg value one
#This is the variable value 0
#This is the $1 value one
#This is the arg value two
#This is the variable value 1
#This is the $1 value two
#This is the arg value three
#This is the variable value 2
#This is the $1 value three
#This is the arg value four
#This is the variable value 3
#This is the $1 value four
i=0 # variable i increment using let
for arg in $@ # you don’t need in $@ because by default it is that
do
echo This is the arg value $arg
echo This is the variable value $i
echo This is the ’$1’ value $1
let i=i+1
shift
done
exit 0
[campbell@moose ~]$ echo $$
25374
[campbell@moose ~]$ ps
PID TTY TIME CMD
25374 pts/2 00:00:00 bash
25746 pts/2 00:00:00 ps
Note, that two processes are running. One is the bash shell that you interact with when you log in and the other is the ps command. If we use “ps -l” we can see that the bash shell process (PID 7996) is in a wait state. The Linux scheduler puts processes into various states depending on what they are doing. They can be executing, ready to execute but waiting on the scheduler queue or blocked or waiting on some signal or event. Here the bash shell is waiting for the ps command process to complete. Operating systems are very neat in the way they make it look like multiple processes or tasks are executing simultaneously when they are not!
[campbell@moose cs50]$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 529 7996 7995 0 75 0 - 1131 wait pts/2 00:00:00 bash
0 R 529 8456 7996 0 77 0 - 1102 - pts/2 00:00:00 ps
Checkout. Let’s look at how the special character $@ can be used with the for..in construct. The description in the script file “whos.sh” describes what the script does. It introduces a number of new ideas. Take a look at the script and see if you can work out what is going on. We will discuss how it works below. First read the script and see if you can work it out without reading the next section first.
Script source: whos.sh
#!/bin/bash
#
# File: whos.sh
#
# Description: Displays information about the user using the first and fifth fields
# in the /etc/passwd file. The first field contains the username
# (e.g., campbell) and the fifth field contains the users full
# name (e.g., Andrew Campbell). You can provide a username or full name and
# whos will return you the full name or username, respectively. This is
# similar in spirit to the finger utility (check it out).
#
# Input: List of arguments can be usernames or login names.
#
# Output: List of usernames or login names.
#
# Adapted from A Practical Guide to Linux (Sobell)
if [ $# -eq 0 ]
then
echo "Usage: whos arg needs to be [list of username or full name]" 1>&2
exit 1
fi
for arg
do
awk -F: ’{print $1, $5}’ /etc/passwd | grep -i "$arg"
done
exit 0
Note, we use -eq above to test if something is equal. We can also use == and != In addition, -lt means less than, -gt means greater than and -ne not equal to.
Here is how you interact with the script once you have made it executable.
[campbell@moose cs50]$ whos.sh "Mirco Musolesi" campbell "Wei Pan"
musolesi Mirco Musolesi
campbell Andrew Campbell
pway Wei Pan
[campbell@moose cs50]$ whos.sh musolesi "Andrew Campbell" pway
musolesi Mirco Musolesi
campbell Andrew Campbell
pway Wei Pan
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.