cmd2 is a tool for building interactive command line applications in Python. Its goal is to make it quick and easy for developers to build feature-rich and user-friendly interactive command line applications. It provides a simple API which is an extension of Python's built-in cmd module. cmd2 provides a wealth of features on top of cmd to make your life easier and eliminates much of the boilerplate code which would be necessary when using cmd.
Click on image below to watch a short video demonstrating the capabilities of cmd2:
history
command and <Ctrl>+r
) - optionally persistentrun_script
(@
) and _relative_run_script
(@@
)run_pyscript
!
|
>
, >>
>
, >>
with no filename send output to paste buffer (clipboard)py
enters interactive Python console (opt-in ipy
for IPython console)cmd2.Cmd.ppaged()
?
and !
)alias
commandargparse
, including support for subcommandsargparse
flags when using one of the cmd2
argparse
decoratorshistory -t
or run_script -t
ansi.style()
cmd2
will end support for Python 3.5 on August 31, 2020. Python 3.5 was released
on Sept. 13, 2015 and its end-of-life is planned for September 2020.
New versions of cmd2
will stop supporting Python 3.5 in a few months. We are very much looking forward to being able to use
features added in Python 3.6 such as f-strings.
On all operating systems, the latest stable version of cmd2
can be installed using pip:
pip install -U cmd2
cmd2 works with Python 3.5+ on Windows, macOS, and Linux. It is pure Python code with few 3rd-party dependencies.
For information on other installation options, see Installation Instructions in the cmd2 documentation.
The latest documentation for cmd2 can be read online here: https://cmd2.readthedocs.io/en/latest/
It is available in HTML, PDF, and ePub formats.
Instructions for implementing each feature follow.
Extension of the cmd
module. So capabilities provided by cmd
still exist
cmd2.Cmd
, let's say you call this class MyApp
import cmd2
class MyApp(cmd2.Cmd):
pass
class MyApp(cmd2.Cmd):
def do_foo(self, args):
"""This docstring is the built-in help for the foo command."""
self.poutput(cmd2.style('foo bar baz', fg=cmd2.fg.red))
argparse
decorators mentioned belowargparse
decorators)cmd
app to cmd2
cmd2
app using the built-in REPL by executing the cmdloop methodSearchable command history
<Ctrl>+r
, arrow keys, and other Readline Shortcut keyscmd2
history
command provides flexible and powerful search
Cmd.exclude_from_history
.help history
in any cmd2
application for more informationpersistent_history_file
argument to cmd2.Cmd
initializerSimple scripting using text files with one command + arguments per line
cmd2
docs for more infocmd2
application with the run_script
command (or @
shortcut)Powerful and flexible built-in Python scripting of your application using the run_pyscript
command
cmd2
application with the ability to also call custom cmd2
commandscmd2
commands in a run_pyscript
is essentially identical to what they would enter on the command linecmd2
docs for more infoParsing commands with argparse
argparse.ArgumentParser
to parse command arguments
cmd2.with_argparser
- all arguments are parsed by the ArgumentParser
cmd2.with_argparser_and_unknown_args
- any arguments not parsed by the ArgumentParser
get passed as a listimport argparse
from cmd2 import with_argparser
argparser = argparse.ArgumentParser()
argparser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
argparser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
argparser.add_argument('words', nargs='+', help='words to say')
@with_argparser(argparser)
def do_speak(self, args):
"""Repeats what you tell me to."""
words = []
for word in args.words:
if args.piglatin:
word = '%s%say' % (word[1:], word[0])
if args.shout:
word = word.upper()
words.append(word)
self.stdout.write('{}\n'.format(' '.join(words)))
See Argument Processing in the docs for more details
NOTE: cmd2
also provides the Cmd2ArgumentParser
customization of argparse.ArgumentParser
for prettier formatting
of help and error messages.
cmd2
applications function like a full-featured shell in many ways (and are cross-platform)
!
or shell
>
for overwrite or >>
for append
>
/>>
, then output goes to the clipboard/pastebuffer|
alias
commandmacro
command (similar to aliases, but allow arguments)set
commandcmd2.Cmd.ppaged()
Top-notch tab completion capabilities which are easy to use but very powerful
cmd2
discussed below mean you would rarely have to implement this from scratchargparse
decorators have automatic tab completion of argparse
flags
basic_complete
helper method for tab completion against a listpath_complete
helper method provides flexible tab completion of file system paths
delimiter_complete
helper method for tab completion against a list but each match is split on a delimiter
flag_based_complete
helper method for tab completion based on a particular flag preceding the token being completedindex_based_complete
helper method for tab completion based on a fixed position in the input string
flag_based_complete()
and index_based_complete()
are basic methods and should only be used if you are not
familiar with argparse. The recommended approach for tab completing positional tokens and flags is to use
argparse-based completioncmd2
in combination with argparse
also provide several advanced capabilities for automatic tab completion
Multi-line commands
Any command accepts multi-line input when its name is listed the multiline_commands
optional argument to
cmd2.Cmd.__init
. The program will keep expecting input until a line ends with any of the characters listed in the
terminators
optional argument to cmd2.Cmd.__init__()
. The default terminators are ;
and \n
(empty newline).
Special-character shortcut commands (beyond cmd's "@" and "!")
To create a single-character shortcut for a command, update Cmd.shortcuts
.
Asynchronous alerts based on events happening in background threads
cmd2
provides the following helper methods for providing information to users asynchronously even though the cmd2
REPL is a line-oriented command interpreter:
async_alert
- display an important message to the user while they are at the prompt in between commands
async_update_prompt
- update the prompt while the user is still typing at it
set_window_title
- set the terminal window title
cmd2
app withinExample cmd2 application (examples/example.py):
#!/usr/bin/env python
# coding=utf-8
"""
A sample application for cmd2.
"""
import argparse
import random
import sys
import cmd2
class CmdLineApp(cmd2.Cmd):
""" Example cmd2 application. """
# Setting this true makes it run a shell command if a cmd2/cmd command doesn't exist
# default_to_shell = True
MUMBLES = ['like', '...', 'um', 'er', 'hmmm', 'ahh']
MUMBLE_FIRST = ['so', 'like', 'well']
MUMBLE_LAST = ['right?']
def __init__(self):
self.maxrepeats = 3
shortcuts = dict(cmd2.DEFAULT_SHORTCUTS)
shortcuts.update({'&': 'speak'})
# Set use_ipython to True to enable the "ipy" command which embeds and interactive IPython shell
super().__init__(use_ipython=False, multiline_commands=['orate'], shortcuts=shortcuts)
# Make maxrepeats settable at runtime
self.add_settable(cmd2.Settable('maxrepeats', int, 'max repetitions for speak command'))
speak_parser = argparse.ArgumentParser()
speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
speak_parser.add_argument('words', nargs='+', help='words to say')
@cmd2.with_argparser(speak_parser)
def do_speak(self, args):
"""Repeats what you tell me to."""
words = []
for word in args.words:
if args.piglatin:
word = '%s%say' % (word[1:], word[0])
if args.shout:
word = word.upper()
words.append(word)
repetitions = args.repeat or 1
for i in range(min(repetitions, self.maxrepeats)):
# .poutput handles newlines, and accommodates output redirection too
self.poutput(' '.join(words))
do_say = do_speak # now "say" is a synonym for "speak"
do_orate = do_speak # another synonym, but this one takes multi-line input
mumble_parser = argparse.ArgumentParser()
mumble_parser.add_argument('-r', '--repeat', type=int, help='how many times to repeat')
mumble_parser.add_argument('words', nargs='+', help='words to say')
@cmd2.with_argparser(mumble_parser)
def do_mumble(self, args):
"""Mumbles what you tell me to."""
repetitions = args.repeat or 1
for i in range(min(repetitions, self.maxrepeats)):
output = []
if (random.random() < .33):
output.append(random.choice(self.MUMBLE_FIRST))
for word in args.words:
if (random.random() < .40):
output.append(random.choice(self.MUMBLES))
output.append(word)
if (random.random() < .25):
output.append(random.choice(self.MUMBLE_LAST))
self.poutput(' '.join(output))
if __name__ == '__main__':
app = CmdLineApp()
sys.exit(app.cmdloop())
The following is a sample session running example.py. Thanks to Cmd2's built-in transcript testing capability, it also serves as a test suite for example.py when saved as transcript_regex.txt. Running
python example.py -t transcript_regex.txt
will run all the commands in the transcript against example.py
, verifying that the output produced
matches the transcript.
example/transcript_regex.txt:
# Run this transcript with "python example.py -t transcript_regex.txt"
# Anything between two forward slashes, /, is interpreted as a regular expression (regex).
# The regex for editor will match whatever program you use.
# regexes on prompts just make the trailing space obvious
(Cmd) set
allow_style: '/(Terminal|Always|Never)/'
debug: False
echo: False
editor: /.*?/
feedback_to_output: False
maxrepeats: 3
quiet: False
timing: False
Regular expressions can be used anywhere within a transcript file simply by enclosing them within forward slashes, /
.
If you think you've found a bug, please first read through the open Issues. If you're confident it's a new bug, go ahead and create a new GitHub issue. Be sure to include as much information as possible so we can reproduce the bug. At a minimum, please state the following:
cmd2
versionHere are a few examples of open-source projects which use cmd2
: