Lab 2: Shell Program
Jan. 17/18, 2007
[153 Home]      [Introduction]      [How to write a shell?]      [What to do in lab?]      [Resources]

Introduction
  1. What is a shell?
    A shell is a command line interpreter. It reads user input and execute commands. The common shells are "Bourne shell" (/bin/sh) and "Bourne-again shell" (/bin/bash).
  2. Basic Shell Operation
    1. Print a prompt.
    2. Get the command line.
    3. Parse the command.
    4. Find the file.
    5. Prepare the parameters.
    6. Execute the command.
  3. Advanced Shell Features
    1. Put a process in the background when & is used.
    2. Redirect input/output with <, > and >>.
    3. Feed the output of one program to the input of another program through a pipe with |.
    4. Execute previous commands in the history list.

How to write a shell?
  1. Write a shell that performs an endless loop until the exit command is received from stdin. Inside the loop body, your shell should first print the prompt character, wait for the user to type a command; then parse the command line, extract the command and its arguments (if any); finally fork a child process to execute the command, and wait for its completion.
  2. Add support for input redirection.
  3. Add support for output redirection.
  4. Add support for pipes.
  5. Add support for running programs in the background.
  6. Add support for executing previous commands.
  7. Add support for all combinations of special control characters. (extra credit).

What to do in lab?
  1. Write a program that creates a child process: the child process executes the command "wc -l". The standard input of the command is taken from the file /etc/passwd. The parent process waits for the child to finish before continuing execution.
    Goal: This exercise shows how the "<" operator should work.
    Hint: Use fork(), exec(), wait() for process control, and open(), close(), dup() for file operations.

  2. Write a program that creates a child process: the child process executes the command "ls -l /". The standard output of the command is sent to the file listroot.txt. The parent process waits for the child to finish before continuing execution.
    Goal: This exercise shows how the ">" operator should work.
    Hint: Use creat() to create a new file or rewrite an existing one. It is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC, but "mode" must be specified when O_CREAT is in the flags.

  3. Write a program that creates two children processes. The first one sends its process ID to the second one through a pipe.
    Goal: This exercise shows how to create two or more child processes, and how to send a message through a pipe.
    Hint: Use pipe() to create a pipe, and read(), write() to read from / write to the pipe.

  4. Write a program that creates two child processes. The first one executes the command "ps ax". Its output is redirected to a pipe. The second one executes the command "grep bash". Its input is redirected from the pipe that the first process' output is written to. So the overall command lists all the running "bash" shells.
    Goal: This exercise shows how the "|" operator should work.
    Hint: Redirect the first command's stdout to the pipe, while redirect the second command's stdin from the pipe. Remember to close the write end of the pipe so that "grep" won't wait for the input forever.

Resources
  1. Lab manual: p.67-82
  2. Online Man Pages
  3. Unix Shell from Wikipedia