A Simple Unix Shell in Python
Here is an absolute bare-minimum Unix shell written in just 36 lines of Python
(including a few blank lines). It doesn’t do pipelines, input/output redirection,
tab-completion or have a command history, it’s just a really light wrapper around
the fork, execv and wait system calls, using the os
module. The only internally implemented function is cd because a shell
is a painful thing to use without it.
from os import chdir, execv, fork, getenv, wait
from os.path import exists
from sys import exit
while True:
# Get input
prompt = getenv("PS1", "$ ")
try:
input = raw_input(prompt)
except EOFError:
exit()
# Parse input
argv = input.split()
command = argv[0]
# Do inbuilts
if command == "cd":
if len(argv) == 1:
chdir(getenv("HOME", "/"))
else:
chdir(argv[1])
# Do external
else:
found = False
path = getenv("PATH")
for dir in path.split(":"):
if exists("/".join((dir, command))):
found = True
if(fork() == 0):
execv("/".join((dir, command)), argv)
else:
wait()
if not found:
print "%s: Not found" % command
This works quite smoothly, it doesn’t feel laggy or anything when you’re
actually using it. I suppose this isn’t unusual because the Python code in use
probably just directly calls the underlying C system calls. It’s really pretty
neat, if not slightly silly.
I have a somewhat more complicated version working, but at the moment it’s still
looking a bit too ugly to post in a blog entry – it handles interpolation of
environment variables, multiple semi-colon delimited commands on a line and has the
beginnings of pipeline and redirection support.
I think I’ll end up writing an article that explains how Unix shells work,
using a Python shell as an example (because it’s much easier for the average
person to read than C), and put the complete shell up on my
software page.
On an unrelated note, here’s Super Mario World implemented in Javascript. Wow.

[...] a closing note, returning to the subject of improving my Javascript skills: In a previous entry I posted a link to a level of Super Mario World implemented in 14 kb of Javascript. I learned the [...]
[...] A while ago I posted the code for a simple Unix shell written in Python. Not too long after this I expressed my delight at discovering the Python standard library’s cmd module. It turns out that these two concepts go together really well. Here’s a much nicer simple Unix shell, less than 100 lines long. It still lacks input/output redirection or pipes, but by virtue of subclassing Cmd it has gained a command line history and tab completion. The tab completion is not the smoothest you’ll ever see – this is basically the first thing I could get almost working – but I think this solidly demonstrates that Cmd makes a fine base for a Pythonic Unix shell. [...]