CMD module: building a Command Line Interpreter using Python.

I’ve been searching documentation about build a Command Line Interpreter (CLI) from some time ago. My requirements were:

  • I was needed a command history
  • I was needed TAB auto-completion.
  • … a easy framework.

Against I could expect, I didn’t found a lot of information on Internet about this aim. So after some time searching documentation about it, I had some luck and I finally found some refers to cmd Python module (oh, what surprise!):

Next lines, show a simple example about how it work:

import cmd

class HelloWorld(cmd.Cmd):
    """Simple command processor example."""

    def do_greet(self, person):
        if person:
            print "hi,", person
        else:
            print 'hi'

    def help_greet(self):
        print '\n'.join([ 'greet [person]',
                           'Greet the named person',
                           ])

    def do_EOF(self, line):
        return True

if __name__ == '__main__':
    HelloWorld().cmdloop()

… and this is a example of use:

$ python cmd_do_help.py
(Cmd) help greet
greet [person]
Greet the named person

One extra reference:

CDM2 is a extentesion of CMD. It adds several features for command-prompt tools:

  • Searchable command history (commands: “hi”, “li”, “run”)
  • Load commands from file, save to file, edit commands in file
  • Multi-line commands
  • Case-insensitive commands
  • Special-character shortcut commands (beyond cmd’s “@” and “!”)
  • Settable environment parameters
  • Parsing commands with flags
  • > (filename), >> (filename) redirect output to file
  • < (filename) gets input from file
  • bare >, >>, < redirect to/from paste buffer
  • accepts abbreviated commands when unambiguous
  • py enters interactive Python console
  • test apps against sample session transcript (see example/example.py)

Defining function args as list of arguments for Python

Saltycrane

Python offers a way to define functions args as a tuple. The syntax is similar to C language, we’ll use *args to refer the tuple of arguments which are used in the function invocation.

def test_args(*args):
    for arg in args:
        print "another arg:", arg  

test_args(1, "two", 3)

Results:

another arg: 1
another arg: two
another arg: 3

Using *args when calling a function

Also, this special syntax can be used, not only in function definitions, but also when calling a function.

def test_args_call(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3

args = ("two", 3)
test_args_call(1, *args)

Results:

arg1: 1
arg2: two
arg3: 3

More info about:

San Xurxo, the great lonely beach

This is a well known beach by the Ferrol people. It is a very beautiful place, with a lot of pretty views. This place has some kind of magic … nature, the brave sea, waves,  bad weather in autum …  all of these things give to this beach his intense coctel … of life.

But this place is not usally frequented by many people. Against of this, this natural site is seldom crouded. This is the oposite to the use of Doniños beach. Doniños keep a lot of people during all the summer. Actually, I prefer the first one rather than the second.

Officially, San Xurxo beach is called in two different ways: the southest part is called San Xurxo, but the  northest part is called Esmelle. This fact is because these two parts of the beach are owned by differents town councils.

 

Esmelle in summer time

The best documentation in the blackboard, … always

 

IPTables
IPTables

 

This diagram is chairing my work office. It has been drawn in a little blackboard  so that it is easilly visible for all members of the team. Many times, look up it is more useful than a big effort  of our mind.

The diagram show the different tables that IPTables is composited, the IP packages logic-flow arround the tables and try to show the relation between IPTables and the route tables of the system.

Is not the same …

Usually, we don’t note  little, but relevant, differents in the code that we are reviewing. For example, the two next classes, apparently, are equivalents:

  class A:
    l = []
    __init__(self):
      ...
  class B:
    def __init__(self):
      self.l = []

    ...

But, really, this two classes are differ in their behavior:

  >>> a = A()
  >>> a.l.append(1)
  >>> a2 = A()
  >>> a2.l.append(2)
  >>> print a.l
  [1,2]
  >>> b = B()
  >>> b.l.append(1)
  >>> b2 = B()
  >>> b2.l.append(2)
  >>> print b.1
  [1]

Class A, due to l var is defined in class definition, share the l var between all A objects instanciates.