cmd
— Support for line-oriented command interpreters¶
Source code:Lib/cmd.py
TheCmd
class provides a simple framework for writing line-orientedcommand interpreters. These are often useful for test harnesses, administrativetools, and prototypes that will later be wrapped in a more sophisticatedinterface.
- classcmd.Cmd(completekey='tab',stdin=None,stdout=None)¶
A
Cmd
instance or subclass instance is a line-oriented interpreterframework. There is no good reason to instantiateCmd
itself; rather,it’s useful as a superclass of an interpreter class you define yourself in orderto inheritCmd
’s methods and encapsulate action methods.The optional argumentcompletekey is the
readline
name of a completionkey; it defaults toTab. Ifcompletekey is notNone
andreadline
is available, command completion is done automatically.The optional argumentsstdin andstdout specify the input and output fileobjects that the Cmd instance or subclass instance will use for input andoutput. If not specified, they will default to
sys.stdin
andsys.stdout
.If you want a givenstdin to be used, make sure to set the instance’s
use_rawinput
attribute toFalse
, otherwisestdin will beignored.
Cmd Objects¶
ACmd
instance has the following methods:
- Cmd.cmdloop(intro=None)¶
Repeatedly issue a prompt, accept input, parse an initial prefix off thereceived input, and dispatch to action methods, passing them the remainder ofthe line as argument.
The optional argument is a banner or intro string to be issued before the firstprompt (this overrides the
intro
class attribute).If the
readline
module is loaded, input will automatically inheritbash-like history-list editing (e.g.Control-P scrolls backto the last command,Control-N forward to the next one,Control-Fmoves the cursor to the right non-destructively,Control-B moves thecursor to the left non-destructively, etc.).An end-of-file on input is passed back as the string
'EOF'
.An interpreter instance will recognize a command name
foo
if and only if ithas a methoddo_foo()
. As a special case, a line beginning with thecharacter'?'
is dispatched to the methoddo_help()
. As anotherspecial case, a line beginning with the character'!'
is dispatched to themethoddo_shell()
(if such a method is defined).This method will return when the
postcmd()
method returns a true value.Thestop argument topostcmd()
is the return value from the command’scorrespondingdo_*()
method.If completion is enabled, completing commands will be done automatically, andcompleting of commands args is done by calling
complete_foo()
withargumentstext,line,begidx, andendidx.text is the string prefixwe are attempting to match: all returned matches must begin with it.line isthe current input line with leading whitespace removed,begidx andendidxare the beginning and ending indexes of the prefix text, which could be used toprovide different completion depending upon which position the argument is in.
- Cmd.do_help(arg)¶
All subclasses of
Cmd
inherit a predefineddo_help()
. Thismethod, called with an argument'bar'
, invokes the corresponding methodhelp_bar()
, and if that is not present, prints the docstring ofdo_bar()
, if available. With no argument,do_help()
lists allavailable help topics (that is, all commands with correspondinghelp_*()
methods or commands that have docstrings), and also lists anyundocumented commands.
- Cmd.onecmd(str)¶
Interpret the argument as though it had been typed in response to the prompt.This may be overridden, but should not normally need to be; see the
precmd()
andpostcmd()
methods for useful execution hooks. Thereturn value is a flag indicating whether interpretation of commands by theinterpreter should stop. If there is ado_*()
method for the commandstr, the return value of that method is returned, otherwise the return valuefrom thedefault()
method is returned.
- Cmd.emptyline()¶
Method called when an empty line is entered in response to the prompt. If thismethod is not overridden, it repeats the last nonempty command entered.
- Cmd.default(line)¶
Method called on an input line when the command prefix is not recognized. Ifthis method is not overridden, it prints an error message and returns.
- Cmd.completedefault(text,line,begidx,endidx)¶
Method called to complete an input line when no command-specific
complete_*()
method is available. By default, it returns an empty list.
- Cmd.columnize(list,displaywidth=80)¶
Method called to display a list of strings as a compact set of columns.Each column is only as wide as necessary.Columns are separated by two spaces for readability.
- Cmd.precmd(line)¶
Hook method executed just before the command lineline is interpreted, butafter the input prompt is generated and issued. This method is a stub in
Cmd
; it exists to be overridden by subclasses. The return value isused as the command which will be executed by theonecmd()
method; theprecmd()
implementation may re-write the command or simply returnlineunchanged.
- Cmd.postcmd(stop,line)¶
Hook method executed just after a command dispatch is finished. This method isa stub in
Cmd
; it exists to be overridden by subclasses.line is thecommand line which was executed, andstop is a flag which indicates whetherexecution will be terminated after the call topostcmd()
; this will be thereturn value of theonecmd()
method. The return value of this method willbe used as the new value for the internal flag which corresponds tostop;returning false will cause interpretation to continue.
- Cmd.preloop()¶
Hook method executed once when
cmdloop()
is called. This method is a stubinCmd
; it exists to be overridden by subclasses.
- Cmd.postloop()¶
Hook method executed once when
cmdloop()
is about to return. This methodis a stub inCmd
; it exists to be overridden by subclasses.
Instances ofCmd
subclasses have some public instance variables:
- Cmd.prompt¶
The prompt issued to solicit input.
- Cmd.identchars¶
The string of characters accepted for the command prefix.
- Cmd.lastcmd¶
The last nonempty command prefix seen.
- Cmd.cmdqueue¶
A list of queued input lines. The cmdqueue list is checked in
cmdloop()
when new input is needed; if it is nonempty, its elementswill be processed in order, as if entered at the prompt.
- Cmd.intro¶
A string to issue as an intro or banner. May be overridden by giving the
cmdloop()
method an argument.
- Cmd.doc_header¶
The header to issue if the help output has a section for documented commands.
- Cmd.misc_header¶
The header to issue if the help output has a section for miscellaneous helptopics (that is, there are
help_*()
methods without correspondingdo_*()
methods).
- Cmd.undoc_header¶
The header to issue if the help output has a section for undocumented commands(that is, there are
do_*()
methods without correspondinghelp_*()
methods).
- Cmd.ruler¶
The character used to draw separator lines under the help-message headers. Ifempty, no ruler line is drawn. It defaults to
'='
.
- Cmd.use_rawinput¶
A flag, defaulting to true. If true,
cmdloop()
usesinput()
todisplay a prompt and read the next command; if false,sys.stdout.write()
andsys.stdin.readline()
are used. (This means that by importingreadline
, on systems that support it, the interpreter will automaticallysupportEmacs-like line editing and command-history keystrokes.)
Cmd Example¶
Thecmd
module is mainly useful for building custom shells that let auser work with a program interactively.
This section presents a simple example of how to build a shell around a few ofthe commands in theturtle
module.
Basic turtle commands such asforward()
are added to aCmd
subclass with method nameddo_forward()
. The argument isconverted to a number and dispatched to the turtle module. The docstring isused in the help utility provided by the shell.
The example also includes a basic record and playback facility implemented withtheprecmd()
method which is responsible for converting the input tolowercase and writing the commands to a file. Thedo_playback()
methodreads the file and adds the recorded commands to thecmdqueue
forimmediate playback:
importcmd,sysfromturtleimport*classTurtleShell(cmd.Cmd):intro='Welcome to the turtle shell. Type help or ? to list commands.\n'prompt='(turtle) 'file=None# ----- basic turtle commands -----defdo_forward(self,arg):'Move the turtle forward by the specified distance: FORWARD 10'forward(*parse(arg))defdo_right(self,arg):'Turn turtle right by given number of degrees: RIGHT 20'right(*parse(arg))defdo_left(self,arg):'Turn turtle left by given number of degrees: LEFT 90'left(*parse(arg))defdo_goto(self,arg):'Move turtle to an absolute position with changing orientation. GOTO 100 200'goto(*parse(arg))defdo_home(self,arg):'Return turtle to the home position: HOME'home()defdo_circle(self,arg):'Draw circle with given radius an options extent and steps: CIRCLE 50'circle(*parse(arg))defdo_position(self,arg):'Print the current turtle position: POSITION'print('Current position is%d%d\n'%position())defdo_heading(self,arg):'Print the current turtle heading in degrees: HEADING'print('Current heading is%d\n'%(heading(),))defdo_color(self,arg):'Set the color: COLOR BLUE'color(arg.lower())defdo_undo(self,arg):'Undo (repeatedly) the last turtle action(s): UNDO'defdo_reset(self,arg):'Clear the screen and return turtle to center: RESET'reset()defdo_bye(self,arg):'Stop recording, close the turtle window, and exit: BYE'print('Thank you for using Turtle')self.close()bye()returnTrue# ----- record and playback -----defdo_record(self,arg):'Save future commands to filename: RECORD rose.cmd'self.file=open(arg,'w')defdo_playback(self,arg):'Playback commands from a file: PLAYBACK rose.cmd'self.close()withopen(arg)asf:self.cmdqueue.extend(f.read().splitlines())defprecmd(self,line):line=line.lower()ifself.fileand'playback'notinline:print(line,file=self.file)returnlinedefclose(self):ifself.file:self.file.close()self.file=Nonedefparse(arg):'Convert a series of zero or more numbers to an argument tuple'returntuple(map(int,arg.split()))if__name__=='__main__':TurtleShell().cmdloop()
Here is a sample session with the turtle shell showing the help functions, usingblank lines to repeat commands, and the simple record and playback facility:
Welcome to the turtle shell. Type help or ? to list commands.(turtle) ?Documented commands (type help <topic>):========================================bye color goto home playback record rightcircle forward heading left position reset undo(turtle) help forwardMove the turtle forward by the specified distance: FORWARD 10(turtle) record spiral.cmd(turtle) positionCurrent position is 0 0(turtle) headingCurrent heading is 0(turtle) reset(turtle) circle 20(turtle) right 30(turtle) circle 40(turtle) right 30(turtle) circle 60(turtle) right 30(turtle) circle 80(turtle) right 30(turtle) circle 100(turtle) right 30(turtle) circle 120(turtle) right 30(turtle) circle 120(turtle) headingCurrent heading is 180(turtle) forward 100(turtle)(turtle) right 90(turtle) forward 100(turtle)(turtle) right 90(turtle) forward 400(turtle) right 90(turtle) forward 500(turtle) right 90(turtle) forward 400(turtle) right 90(turtle) forward 300(turtle) playback spiral.cmdCurrent position is 0 0Current heading is 0Current heading is 180(turtle) byeThank you for using Turtle