ish - kind of like a shell
In this problem set, you will implement the shell ish, a
command interpreter with a syntax and behavior similar to bash.
Initialization and Termination
When first started, ish normally performs commands from the
file ~/.ishrc, provided that it is readable. Typically, the
~/.ishrc file contains commands to specify the terminal type
and environment. (Here is an example .ishrc file, which doubles
as a test case.) ish
terminates when the user types CTRL-D or exit.
After startup processing, the shell interactively processes commands
from the terminal, prompting with %. The shell repeatedly
performs the following actions: a line of command input is read and
broken into words; this sequence of words is parsed (as
described under USAGE); and the shell executes the commands in
the current line.
The shell splits input lines into words separated by spaces or tabs,
with the following exceptions:
The special characters '|', '<', and '>' form separate
Special characters preceded by a backslash '\' character prevents
the shell from interpreting them as special characters.
Strings enclosed in double quotes ( " ) form part or all
of a single word. Special characters inside of strings do not form
Command Line Parsing
A simple command is a sequence of words, the first of which
specifies the command to be executed. A pipeline is a sequence
of one or more simple commands separated by '|' . With '|', the
standard output of the preceding command is redirected to the standard
input of the command that follows.
You may assume that each simple command is of the form
'command arguments redirection'
and that the syntax
'command redirection arguments'
The following metacharacters indicate that the subsequent word is the
name of a file to which the command's standard input or standard
output is redirected.
< Redirect the standard input.
> Redirect the standard output to a file. If the file
does not exist, it is created. If it does exist, it is overwritten; its
previous contents are lost.
If the command is an ish shell built-in, the shell executes it
directly. Otherwise, the shell searches for a file by that name with
execute access. If the command-name begins with a '/', the shell
takes it as a full pathname, and tries to execute it. If the
command-name does not begin with a '/', the shell attempts to resolve
it to a pathname, searching each directory in the PATH variable for
When a file is found that has proper execute permissions, the shell
forks a new process and passes it, along with its arguments, to the OS
using the execv or execl system call. (Do not use the
execvp or execlp calls; your shell is responsible for
searching the search path.) The OS then attempts to overlay the new
process with the desired program. If the file is an executable binary
the OS succeeds, and begins executing the new process. If the file
does not have execute permissions, or if the pathname matches a
directory, a "permission denied" message is displayed. If the pathname
cannot be resolved a "command not found" message is displayed. If
either of these errors occur with any component of a pipeline the
entire pipeline is aborted, although some of the components of the
pipeline may have already started running.
A pipeline is completed (i.e., returns to the prompt) only when all
the commands that form a part of the pipeline and that are being
executed in the foreground are completed.
Environment variables may be accessed via the export and
unset built-in commands. Initially, ish inherits
environment variables from its parent. ish then maintains the
environment variables internally using the C library routines
setenv and unsetenv. The only environment variable that
ish needs to interpret is PATH; all other environment variables
can be set and unset in ish using the above built-in commands,
but are not interpreted.
Background Processes and Job Control
All jobs run in the foreground. You need not support job control.
However, you do need to be able to kill, using CTRL-C, the current
In addition to export and unset (described above), you
need to support the following built-in commands. Built-in commands
execute as part of the ish process; you need not fork another
process. Hence, you need not support built-ins as part of a pipeline.
|cd [ dir ]
||Change the shell's working directory to directory dir. If no
argument is given, change to the home directory of the user.
|| Exit ish.
~/.ishrc Read at beginning of execution
by each shell.
Words can be no longer than 1024 characters. Lines can be no longer
than 2048 characters.
Submit your program (makefile, all source code, readme file)
electronically with the command
Your solution is due by 11:59 p.m., Tuesday, January 15, 2002. This
is a hard deadline; no late work will be accepted.
Support a primitive history mechanism that includes the history
built-in command, and the ability re-execute a past command by typing
!prefix, just as in bash. (You need not support editing of this
previous command to get the extra credit.) Note that since it is
possible to include the history built-in in a pipeline, you
will need to spawn a sub-shell in this case. This will also allow you
to run export in a pipeline.