To be able to execute a command, the shell needs to find where the command is located
first (in which folder or directory). For this, the shell uses an environment variable
called $PATH that defines search paths for a command. The path environment is a
list of directories, separated by colon ':'.
To see the contents of your $PATH variable in Unix, type at the shell prompt:
echo $PATH
You should see something similar to this:
/bin:/usr/bin:/opt/gnu/bin:/usr/gnu/binThis information is used as follows. When you type in a command at the shell prompt, the shell looks for the executable file in the current directory first. If not found, the shell looks in the directories defined by the search paths in order: /bin first, then /usr/bin, and so on, until either the command is found or the search paths are exhausted. If the command is found, the shell executes it. If not found, the shell simply displays the message "Command not found".
Note that: If the command name starts with the character '/' (root directory) or '.' (current directory), the search path is not used, because the path is explicitly mentioned.
quit
, exit the program (use
strncmp to compare
the first four characters in the user input with "quit")
path
, print out a list of each of the values (or directories)
of the current PATH environment variable, one per line.
To do so, use the getenv library function to obtain a pointer to the string representing the $PATH variable. Copy this string into a local buffer,
then use the function strtok to extract individual tokens from
the string. The delimiter in this case is the colon character.
One specific implementation requirement is to save the paths in an array of strings before printing them out. This will come in handy when we will build
more shell functionality in future assignments. Incorporate in your shell a function
void tokenize_PATH();
that creates an array of strings, with each string representing one path from the PATH environment variable.
For example, if the $PATH variable has the value shown above, then this function allocates memory for a global
variable searchpaths as shown below:
To implement the tokenize_PATH function, use the functions InitArray and Insert from
the previous assignment. Then step 4 of this assignment reduces to
simply calling PrintAll.
Do NOT copy these functions into your smartshell.c file. Just include the line
#include "stringarray.h"
at the beginning of your smartshell.c code.
If the user types where filename, consider in turn each directory listed in searchpaths and check if the indicated filename is in that directory. Once you reach a directory containing the file, print the complete path to filename and look no further. For example, if the user types in
where gccyour shell should print our something like
/opt/gnu/bin/gccIf none of the PATH directories (listed in searchpath) contains the file, print "filename not found" (substituting the actual name of the file for the word filename). Your where command should behave exactly like the Unix which command.
To implement this feature, declare a pointer
char * fname;and set it to point to filename in the user command (use strtok twice). For more practice with dynamic memory management, build the complete path for the file in a dynamically allocated buffer
char *fullpath;by looping through searchpaths and using each entry i as follows:
fullpath = (char *)malloc(strlen(searchpaths[i]) + strlen(fname) + 2);
sprintf(fullpath, "%s/%s", searchpaths[i], fname);
free(fullpath);
gcc smartshell.c stringarray.c -o xsmartshellThe two source files will be linked into one executable file called xsmartshell.
To simplify your development process, you may use this Makefile and simply type in make at the shell prompt to compile your code. This saves you from typing in a long command line every time you need to compile your code.
Makefiles are special format files that help build and manage projects composed of multiple modules. The key point to remember is that you need to insert a TAB character (not spaces) before each command in the Makefile. If interested, you may read more about using make and writing Makefiles.
smartshell
directory create a text file named readme
(not readme.txt
, or README
, or Readme
, etc.)
that contains:
Turn in a printout copy of the readme
and smartshell.c
files, and a sample output (one printout per team). If you work on the department Unix system, you will need to copy and paste your code into a text or a Word document in Windows, since you cannot print directly from Unix.
Leave the source code for all exercises in your directory systems/smartshell. Do not make any changes to these files after the due date for this assignment. If you wish to continue working on these exercises after the due date, make a copy of your directory smartshell using the following Unix command:
cp -r ~/systems/smartshell ~/systems/smartshell-copyA new directory called smartshell-copy will be created in your systems directory. You may now make any changes you want to the files in your smartshell-copy directory, at any time.
No credit will be given for code that does not compile. | |
100 | Total points possible |
20 | Program compiles and runs without crashing |
20 | Each command does something resembling the specified action |
50 | Each command works correctly and completely |
5 | You have added some extra "bells and whistles" (use your imagination) |
5 | Your readme file is present |