TWiki> CS385spring12 Web>Homework4 (2012-01-31, Main.jakob)EditAttach

Homework 4 - homebrew command line interpreter

The command line interpreter, or "shell" in Unix is an incredibly powerful tool in the hands of an experienced user. Its main function is to providing an intuitive and efficient way to combine many small commands to create new functionality.

In this homework, we will create our own shell, supporting many of the basic functions available in bash and other popular shells.

Copy the hw4 template to your turn-in directory thus:

svn export svn://

svn add hw4

You will also need to install the readline developer files:

sudo apt-get install libreadline-dev

PATH support

The template code requires the absolute path of the binary you want it to run. Change it to automatically look for the program in all of the directories indicated by PATH, except for filenames that contain a '/'. Thus, make ls do the same thing as /bin/ls, but also make sure that mydir/mybinary still works correctly.

HINT: getenv() to get the environment variable, then strsep() to split it into multiple path strings. Finally, sprintf() to compose a full path out of its components.

Commands with command-line arguments

Support up to 10 command line arguments. For example echo hello world, should produce hello world.

HINT: you could use strsep() to split the arguments into an array, which you then pass to execve().

Redirection to and from files

Support stdin and stdout redirection to and from files. For example, ls > /tmp/templ should create a file (with correct permissions) containing the output of ls. Similarly wc < /tmp/templ should use the file as input, and wc < /tmp/templ > /tmp/count uses both input and output redirection.

HINT: use open() to open a file, and dup2() to change where stdin(0) or stdout(1) points to.


Support piping of the stdout from one command to stdin to another. For example:

ls -l | sort -n -k 5 | cut -c 27-34 > /tmp/sizes

produces a file containing a sorted list of file sizes.

HINT: this is by far the most challenging part of the homework. Use fork() as in the template code to start up multiple concurrent processes, pipe() to create pipes through which processes communicate, and dup2() to redirect output into and out of pipes. Finally, use waitpid() to wait for child processes to finish.

Variable substitution

The template code already supports interpreted scripts. There are a couple of examples in the template directory, ending with .hw4. Add support for command line arguments to such scripts. For example,

./echo.hw4 hello world
hello world hello

Replace any occurrence of $1,$2,$3 etc with the first, second, third command line argument respectively.

HINT: this one will require some manual string manipulation, but strchr() to find each "$", and strncpy() to copy part or all of strings is a good start.

Testing your code

Try running ./test.hw4. Below is the expected output. Of course, the results from "ls" and the number of files will vary depending on what's in your directory.

* Echo seems to work
* Now the directory contents:
Makefile   echo.hw4   hw4      hw4.c      hw4.dSYM      test.hw4
* Now the number of files:
* Now we should see "Hello World":
Hello World
* And now the contents of /tmp/countfile
* Now a list of file sizes

* And finally "hello world hello world"
hello world hello world
Topic revision: r1 - 2012-01-31 - 20:20:21 - Main.jakob
Copyright 2016 The Board of Trustees
of the University of
Helping Women Faculty Advance
Funded by NSF