Projects‎ > ‎


USF Shell - usfsh

Due Tuesday, October 3rd at 11:59pm. Turn into your Project02 GitHub repo.

For this project you are going to develop a mini UNIX shell called usfsh. In order to implement usfsh you will need to understand how to use several UNIX systems calls and how to manipulate kernel provided abstractions such as the file descriptor table. Your shell will support command history and you will implement this history list with a provided C linked list implementation.

Note your implementation of usfsh must run on your RPi in Raspbian. For interactive grading you must demo on your RPi. You should develop entirely on your RPi. Some of the system calls are not identical on Mac OS X and Linux, so if you develop on your Mac, you solution may not compile and run on your RPi. The moral here is to figure out a way to edit and compile directly on your RPi.

The Shell: usfsh

Your shell should print the “[#]$” prompt and wait for user input. For example:


The [0] indicates the command number. The first command executed is 0, then second is 1, etc.

You should be able to execute commands that are in the current directory using the “./” notation:

[1]$ ./hello

You should also be able to execute an command available in the PATH environment variable. For example:

[2]$ ls

If the user types in a command that is not on the PATH, then you should print an error message:

[3]$ foobar
foobar: command not found

You should be able to pass arguments to commands:

[4]$ echo hi there

You need to support file output redirection:

[5]$ echo hi there > hi.txt

This will create or overwrite a file called hi.txt and put the output of the first command into the file.

You need to support pipe redirection:

[6]$ echo world hello | wc

      1       2      12

In both file redirection and pipe redirection you need to support multiple arguments.

Make sure to test your pipe with a large amount of data between two processes:

[7]$ seq 100000 | wc -l


You need to support a built-in “cd” command to change directories:

[8]$ cd foo

[9]$ ls

[10]$ cd ..

[11]$ cd /home
[12]$ cd pi

cd by itself should return you to the home directory.

(Hint: use the chdir system call)

Command history support.

[13]$ history

4 echo hi there

5 echo hi there > hi.txt

6 echo world hello | wc

7 seq 100000 | wc -l

8 cd foo

9 ls

10 cd ..

11  cd /home
12  cd pi
13  history

Note, you should only store the last 10 commands in your history.

Support the ! command to execute something from history:

[14]$ !9

You can also use a string prefix:

[15]$ !seq
seq 100000 | wc -l

You also need to support a built-in "exit" command that will exit usfsh.

[16]$ exit

How history should behave when you don't type a commend, just return:

0]$ ls



[1]$ pwd

[2]$ history

0 ls

1 pwd

2 history


General Requirements

  • You must only use system calls for I/O, with the exception of printf().
  • You can use strtok() for parsing the command line.
  • You must use my provided linked list code for your command 

Extra Credit

Each worth one point.


  • [sh-0] 24 hours early

  • [sh-1] Support file input redirection with "<" (e.g., $ sort < file.txt)

  • [sh-2] Support chaining multiple commands via pipes (e.g., $ ls | sort -r | head -n 3)

  • [sh-3] Support mixing pipe redirection and file redirection (e.g., $ ls | sort -r > out.txt)

  • [sh-4] Support <TAB> command completion (this is hard).

  • [sh-5] Support background processing with & (e.g., $ some_command &)

  • [sh-6] Support for the && shell operator (e.g., $ c1 && c2) Note you must check that c1 succeeded in order to execute c2.

  • [sh-7] Support for the || shell operator

  • [sh-8] Add support for showing the duration (in seconds) of each command in the history list (e.g., 1 [0.02 seconds] ls