1:mod:`cmd` --- Support for line-oriented command interpreters 2============================================================= 3 4.. module:: cmd 5 :synopsis: Build line-oriented command interpreters. 6 7.. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com> 8 9**Source code:** :source:`Lib/cmd.py` 10 11-------------- 12 13The :class:`Cmd` class provides a simple framework for writing line-oriented 14command interpreters. These are often useful for test harnesses, administrative 15tools, and prototypes that will later be wrapped in a more sophisticated 16interface. 17 18.. class:: Cmd(completekey='tab', stdin=None, stdout=None) 19 20 A :class:`Cmd` instance or subclass instance is a line-oriented interpreter 21 framework. There is no good reason to instantiate :class:`Cmd` itself; rather, 22 it's useful as a superclass of an interpreter class you define yourself in order 23 to inherit :class:`Cmd`'s methods and encapsulate action methods. 24 25 The optional argument *completekey* is the :mod:`readline` name of a completion 26 key; it defaults to :kbd:`Tab`. If *completekey* is not :const:`None` and 27 :mod:`readline` is available, command completion is done automatically. 28 29 The optional arguments *stdin* and *stdout* specify the input and output file 30 objects that the Cmd instance or subclass instance will use for input and 31 output. If not specified, they will default to :data:`sys.stdin` and 32 :data:`sys.stdout`. 33 34 If you want a given *stdin* to be used, make sure to set the instance's 35 :attr:`use_rawinput` attribute to ``False``, otherwise *stdin* will be 36 ignored. 37 38 39.. _cmd-objects: 40 41Cmd Objects 42----------- 43 44A :class:`Cmd` instance has the following methods: 45 46 47.. method:: Cmd.cmdloop(intro=None) 48 49 Repeatedly issue a prompt, accept input, parse an initial prefix off the 50 received input, and dispatch to action methods, passing them the remainder of 51 the line as argument. 52 53 The optional argument is a banner or intro string to be issued before the first 54 prompt (this overrides the :attr:`intro` class attribute). 55 56 If the :mod:`readline` module is loaded, input will automatically inherit 57 :program:`bash`\ -like history-list editing (e.g. :kbd:`Control-P` scrolls back 58 to the last command, :kbd:`Control-N` forward to the next one, :kbd:`Control-F` 59 moves the cursor to the right non-destructively, :kbd:`Control-B` moves the 60 cursor to the left non-destructively, etc.). 61 62 An end-of-file on input is passed back as the string ``'EOF'``. 63 64 .. index:: 65 single: ? (question mark); in a command interpreter 66 single: ! (exclamation); in a command interpreter 67 68 An interpreter instance will recognize a command name ``foo`` if and only if it 69 has a method :meth:`do_foo`. As a special case, a line beginning with the 70 character ``'?'`` is dispatched to the method :meth:`do_help`. As another 71 special case, a line beginning with the character ``'!'`` is dispatched to the 72 method :meth:`do_shell` (if such a method is defined). 73 74 This method will return when the :meth:`postcmd` method returns a true value. 75 The *stop* argument to :meth:`postcmd` is the return value from the command's 76 corresponding :meth:`do_\*` method. 77 78 If completion is enabled, completing commands will be done automatically, and 79 completing of commands args is done by calling :meth:`complete_foo` with 80 arguments *text*, *line*, *begidx*, and *endidx*. *text* is the string prefix 81 we are attempting to match: all returned matches must begin with it. *line* is 82 the current input line with leading whitespace removed, *begidx* and *endidx* 83 are the beginning and ending indexes of the prefix text, which could be used to 84 provide different completion depending upon which position the argument is in. 85 86 All subclasses of :class:`Cmd` inherit a predefined :meth:`do_help`. This 87 method, called with an argument ``'bar'``, invokes the corresponding method 88 :meth:`help_bar`, and if that is not present, prints the docstring of 89 :meth:`do_bar`, if available. With no argument, :meth:`do_help` lists all 90 available help topics (that is, all commands with corresponding 91 :meth:`help_\*` methods or commands that have docstrings), and also lists any 92 undocumented commands. 93 94 95.. method:: Cmd.onecmd(str) 96 97 Interpret the argument as though it had been typed in response to the prompt. 98 This may be overridden, but should not normally need to be; see the 99 :meth:`precmd` and :meth:`postcmd` methods for useful execution hooks. The 100 return value is a flag indicating whether interpretation of commands by the 101 interpreter should stop. If there is a :meth:`do_\*` method for the command 102 *str*, the return value of that method is returned, otherwise the return value 103 from the :meth:`default` method is returned. 104 105 106.. method:: Cmd.emptyline() 107 108 Method called when an empty line is entered in response to the prompt. If this 109 method is not overridden, it repeats the last nonempty command entered. 110 111 112.. method:: Cmd.default(line) 113 114 Method called on an input line when the command prefix is not recognized. If 115 this method is not overridden, it prints an error message and returns. 116 117 118.. method:: Cmd.completedefault(text, line, begidx, endidx) 119 120 Method called to complete an input line when no command-specific 121 :meth:`complete_\*` method is available. By default, it returns an empty list. 122 123 124.. method:: Cmd.columnize(list, displaywidth=80) 125 126 Method called to display a list of strings as a compact set of columns. 127 Each column is only as wide as necessary. 128 Columns are separated by two spaces for readability. 129 130 131.. method:: Cmd.precmd(line) 132 133 Hook method executed just before the command line *line* is interpreted, but 134 after the input prompt is generated and issued. This method is a stub in 135 :class:`Cmd`; it exists to be overridden by subclasses. The return value is 136 used as the command which will be executed by the :meth:`onecmd` method; the 137 :meth:`precmd` implementation may re-write the command or simply return *line* 138 unchanged. 139 140 141.. method:: Cmd.postcmd(stop, line) 142 143 Hook method executed just after a command dispatch is finished. This method is 144 a stub in :class:`Cmd`; it exists to be overridden by subclasses. *line* is the 145 command line which was executed, and *stop* is a flag which indicates whether 146 execution will be terminated after the call to :meth:`postcmd`; this will be the 147 return value of the :meth:`onecmd` method. The return value of this method will 148 be used as the new value for the internal flag which corresponds to *stop*; 149 returning false will cause interpretation to continue. 150 151 152.. method:: Cmd.preloop() 153 154 Hook method executed once when :meth:`cmdloop` is called. This method is a stub 155 in :class:`Cmd`; it exists to be overridden by subclasses. 156 157 158.. method:: Cmd.postloop() 159 160 Hook method executed once when :meth:`cmdloop` is about to return. This method 161 is a stub in :class:`Cmd`; it exists to be overridden by subclasses. 162 163 164Instances of :class:`Cmd` subclasses have some public instance variables: 165 166.. attribute:: Cmd.prompt 167 168 The prompt issued to solicit input. 169 170 171.. attribute:: Cmd.identchars 172 173 The string of characters accepted for the command prefix. 174 175 176.. attribute:: Cmd.lastcmd 177 178 The last nonempty command prefix seen. 179 180 181.. attribute:: Cmd.cmdqueue 182 183 A list of queued input lines. The cmdqueue list is checked in 184 :meth:`cmdloop` when new input is needed; if it is nonempty, its elements 185 will be processed in order, as if entered at the prompt. 186 187 188.. attribute:: Cmd.intro 189 190 A string to issue as an intro or banner. May be overridden by giving the 191 :meth:`cmdloop` method an argument. 192 193 194.. attribute:: Cmd.doc_header 195 196 The header to issue if the help output has a section for documented commands. 197 198 199.. attribute:: Cmd.misc_header 200 201 The header to issue if the help output has a section for miscellaneous help 202 topics (that is, there are :meth:`help_\*` methods without corresponding 203 :meth:`do_\*` methods). 204 205 206.. attribute:: Cmd.undoc_header 207 208 The header to issue if the help output has a section for undocumented commands 209 (that is, there are :meth:`do_\*` methods without corresponding :meth:`help_\*` 210 methods). 211 212 213.. attribute:: Cmd.ruler 214 215 The character used to draw separator lines under the help-message headers. If 216 empty, no ruler line is drawn. It defaults to ``'='``. 217 218 219.. attribute:: Cmd.use_rawinput 220 221 A flag, defaulting to true. If true, :meth:`cmdloop` uses :func:`input` to 222 display a prompt and read the next command; if false, :meth:`sys.stdout.write` 223 and :meth:`sys.stdin.readline` are used. (This means that by importing 224 :mod:`readline`, on systems that support it, the interpreter will automatically 225 support :program:`Emacs`\ -like line editing and command-history keystrokes.) 226 227 228.. _cmd-example: 229 230Cmd Example 231----------- 232 233.. sectionauthor:: Raymond Hettinger <python at rcn dot com> 234 235The :mod:`cmd` module is mainly useful for building custom shells that let a 236user work with a program interactively. 237 238This section presents a simple example of how to build a shell around a few of 239the commands in the :mod:`turtle` module. 240 241Basic turtle commands such as :meth:`~turtle.forward` are added to a 242:class:`Cmd` subclass with method named :meth:`do_forward`. The argument is 243converted to a number and dispatched to the turtle module. The docstring is 244used in the help utility provided by the shell. 245 246The example also includes a basic record and playback facility implemented with 247the :meth:`~Cmd.precmd` method which is responsible for converting the input to 248lowercase and writing the commands to a file. The :meth:`do_playback` method 249reads the file and adds the recorded commands to the :attr:`cmdqueue` for 250immediate playback:: 251 252 import cmd, sys 253 from turtle import * 254 255 class TurtleShell(cmd.Cmd): 256 intro = 'Welcome to the turtle shell. Type help or ? to list commands.\n' 257 prompt = '(turtle) ' 258 file = None 259 260 # ----- basic turtle commands ----- 261 def do_forward(self, arg): 262 'Move the turtle forward by the specified distance: FORWARD 10' 263 forward(*parse(arg)) 264 def do_right(self, arg): 265 'Turn turtle right by given number of degrees: RIGHT 20' 266 right(*parse(arg)) 267 def do_left(self, arg): 268 'Turn turtle left by given number of degrees: LEFT 90' 269 left(*parse(arg)) 270 def do_goto(self, arg): 271 'Move turtle to an absolute position with changing orientation. GOTO 100 200' 272 goto(*parse(arg)) 273 def do_home(self, arg): 274 'Return turtle to the home position: HOME' 275 home() 276 def do_circle(self, arg): 277 'Draw circle with given radius an options extent and steps: CIRCLE 50' 278 circle(*parse(arg)) 279 def do_position(self, arg): 280 'Print the current turtle position: POSITION' 281 print('Current position is %d %d\n' % position()) 282 def do_heading(self, arg): 283 'Print the current turtle heading in degrees: HEADING' 284 print('Current heading is %d\n' % (heading(),)) 285 def do_color(self, arg): 286 'Set the color: COLOR BLUE' 287 color(arg.lower()) 288 def do_undo(self, arg): 289 'Undo (repeatedly) the last turtle action(s): UNDO' 290 def do_reset(self, arg): 291 'Clear the screen and return turtle to center: RESET' 292 reset() 293 def do_bye(self, arg): 294 'Stop recording, close the turtle window, and exit: BYE' 295 print('Thank you for using Turtle') 296 self.close() 297 bye() 298 return True 299 300 # ----- record and playback ----- 301 def do_record(self, arg): 302 'Save future commands to filename: RECORD rose.cmd' 303 self.file = open(arg, 'w') 304 def do_playback(self, arg): 305 'Playback commands from a file: PLAYBACK rose.cmd' 306 self.close() 307 with open(arg) as f: 308 self.cmdqueue.extend(f.read().splitlines()) 309 def precmd(self, line): 310 line = line.lower() 311 if self.file and 'playback' not in line: 312 print(line, file=self.file) 313 return line 314 def close(self): 315 if self.file: 316 self.file.close() 317 self.file = None 318 319 def parse(arg): 320 'Convert a series of zero or more numbers to an argument tuple' 321 return tuple(map(int, arg.split())) 322 323 if __name__ == '__main__': 324 TurtleShell().cmdloop() 325 326 327Here is a sample session with the turtle shell showing the help functions, using 328blank lines to repeat commands, and the simple record and playback facility: 329 330.. code-block:: none 331 332 Welcome to the turtle shell. Type help or ? to list commands. 333 334 (turtle) ? 335 336 Documented commands (type help <topic>): 337 ======================================== 338 bye color goto home playback record right 339 circle forward heading left position reset undo 340 341 (turtle) help forward 342 Move the turtle forward by the specified distance: FORWARD 10 343 (turtle) record spiral.cmd 344 (turtle) position 345 Current position is 0 0 346 347 (turtle) heading 348 Current heading is 0 349 350 (turtle) reset 351 (turtle) circle 20 352 (turtle) right 30 353 (turtle) circle 40 354 (turtle) right 30 355 (turtle) circle 60 356 (turtle) right 30 357 (turtle) circle 80 358 (turtle) right 30 359 (turtle) circle 100 360 (turtle) right 30 361 (turtle) circle 120 362 (turtle) right 30 363 (turtle) circle 120 364 (turtle) heading 365 Current heading is 180 366 367 (turtle) forward 100 368 (turtle) 369 (turtle) right 90 370 (turtle) forward 100 371 (turtle) 372 (turtle) right 90 373 (turtle) forward 400 374 (turtle) right 90 375 (turtle) forward 500 376 (turtle) right 90 377 (turtle) forward 400 378 (turtle) right 90 379 (turtle) forward 300 380 (turtle) playback spiral.cmd 381 Current position is 0 0 382 383 Current heading is 0 384 385 Current heading is 180 386 387 (turtle) bye 388 Thank you for using Turtle 389