Olin,

I just realised that there was a amall bug in the program I sent you: If you
typed M-x start-new-shell instead of M-x shell it never creates "*shell*" but
always "*shell<2>*" etc. Here is the file again:

--
Regards, David
===============================================================================
;;; multi-shell.el
;;; Tweak to the comint shell program to allow Multi Shells
;;; David Hughes 5th October 1992

(defun start-new-shell ()
  (interactive)
  (shell -1))

(defun shell (&optional shell-number)
  "Run an inferior shell, with I/O through buffer *shell*.
If buffer exists but shell process is not running, make new shell.
Program used comes from variable explicit-shell-file-name,
 or (if that is nil) from the ESHELL environment variable,
 or else from SHELL if there is no ESHELL.
If a file ~/.emacs_SHELLNAME exists, it is given as initial input.
It is particularly useful to have this file set the environment
variable 'PAGER' to the value 'cat'.
 (Note that this may lose due to a timing error if the shell
  discards input when it starts up.)
The buffer is put in shell-mode, giving commands for sending input
and controlling the subjobs of the shell.  See shell-mode.
See also variable shell-prompt-pattern.

The shell file name (sans directories) is used to make a symbol name
such as `explicit-csh-arguments'.  If that symbol is a variable,
its value is used as a list of arguments when invoking the shell.
Otherwise, one argument `-i' is passed to the shell.

A negative argument causes further shell windows (*shell<2>*,
*shell<3>*, etc.) to be created.  A positive argument causes the shell
window with that number to be selected, instead of *shell* (which is
number 1).  Shells with numbers > 1 must be created explicitly; shell
1 is created automatically if it is selected but does not already
exist.

\(Type \\[describe-mode] in the shell buffer for a list of commands.)"

  (interactive "p")
  (let* ((shell-name
         (cond ((or (null shell-number) (= shell-number 1)) "shell")
          ;; negative arg means find a new shell number
          ((< shell-number 1)
           (if (not (get-buffer "*shell*"))
               "shell"
             (setq shell-number 2)
             (while (get-buffer (concat "*shell<" (int-to-string shell-number) ">*"))
               (setq shell-number (1+ shell-number)))
             (concat "shell<" (int-to-string shell-number) ">")))
          ;; if user is trying to select a shell > 1, check it exists
          ((> shell-number 1)
           (if (get-buffer (concat "*shell<" (int-to-string shell-number) ">*"))
               (concat "shell<" (int-to-string shell-number) ">")
             (error (format "%s does not exist" (concat "*shell<" (int-to-string shell-number) ">*")))))))
         (shell-buffer-name (concat "*" shell-name "*")))

  (cond ((not (comint-check-proc shell-buffer-name))
	 (let* ((prog (or explicit-shell-file-name
			  (getenv "ESHELL")
			  (getenv "SHELL")
			  "/bin/sh"))		     
		(name (file-name-nondirectory prog))
		(startfile (concat "~/.emacs_" name))
		(xargs-name (intern-soft (concat "explicit-" name "-arguments"))))
	   (set-buffer (apply 'make-comint shell-name prog
			      (if (file-exists-p startfile) startfile)
			      (if (and xargs-name (boundp xargs-name))
				  (symbol-value xargs-name)
				  '("-i"))))
	   (shell-mode))))

  (switch-to-buffer shell-buffer-name)))