Give your Python program a shell with the cmd module
There's a Python module that I recently became obsessed with called cmd
(Python docs). You can use it to give your Python programs a shell interface. For some reason, I never knew about this module for a long time, but once I learned about it, I began using it a lot to build some awesome utilities.
Python is one of my favorite languages because it lets you write lots of cool utilities and scripts for getting stuff done. For most small scripts, I'll just pass input as command line arguments but sometimes I'll want something a little more interactive and to give me instant feedback and to maintain a state. That's where the cmd
module really makes it easy to write powerful Python scripts that appeal to my "power user" side.
If you were to do this on your own, you would probably write something like this:
while in_command_loop:
raw_input = input("Prompt>")
if input == 'command_1':
command_1()
elif input == 'command_2':
command_2()
# more commands here...
else:
print "Error"
So that's not too terrible. We loop and get commands as input and run functions. One problem is that we'll spend some time updating this loop when we want to add a new command and that's just another if
statement in this thing. Not elegant. We can do better. We're Python developers.
First thing to know about cmd.Cmd
: you subclass it and customize the subclass to be your command prompt. The methods of this subclass that begin with do_
are now your prompt commands. Here's a trivial example:
from cmd import Cmd
class MyPrompt(Cmd):
def do_hello(self, args):
"""Says hello. If you provide a name, it will greet you with it."""
if len(args) == 0:
name = 'stranger'
else:
name = args
print "Hello, %s" % name
def do_quit(self, args):
"""Quits the program."""
print "Quitting."
raise SystemExit
if __name__ == '__main__':
prompt = MyPrompt()
prompt.prompt = '> '
prompt.cmdloop('Starting prompt...')
Running that gives the following:
Starting prompt...
> help
Documented commands (type help <topic>):
========================================
hello help quit
> help hello
Says hello. If you provide a name, it will greet you with it.
> hello austin
Hello, austin
>
Cool things to notice about this:
- Self documenting commands: Your prompt contains an implicit help
command which will show you some help text for the command. Where does that come from? It's your method doc string!
- Command history: You you press the up and down keys and scroll through a list of commands. Some OS shells already do this for you, but it's still a nice feature.
- Organization: All of your commands are just methods and they all have a command method signature. I like how comfortable this feels compared to a massive block of if... elif... else
statements.
- Lots of features: I didn't touch any of the really neat things, like pre-command and post-command code being executed.
So in conclusion, the cmd
module lets you build a command line shell for your Python program without a lot of extra effort. You get to keep using the command line (like all real geeks use) and get some interactivity.
Written by Austin Keeley
Related protips
6 Responses
Thanks for sharing this tip. I didn't know this module either. I've been looking for that for a while.
Very informative article. I was searching for such example since long time.
Thank you very much.
As someone who has written their own interpreter a few times in other lanuguages, this is a great example. I was off an running quickly after reading this.
How can I pull this interactive shell onto a web page using html?
Or you could just use exec(command)
Thanks for the article. It's amazing how close my old code was to your pre-cmd version. I became a true believer in minutes and re-did my command line module. Thanks again, Douglas