[Bits and pieces] Custom python shell

Today we will have some fun with python and try to create a "framework" using python shell. We will make a custom python shell with the ability of loading modules. You all probably know how python shell looks like, but here it is:

So let's start with our script (we will build it step by step):

#!/usr/bin/env python

import sys
import os

os.environ['PYTHONINSPECT'] = 'True'

 

os.environ is a mapping object that represents a string enviroment. In our case enviroment is set to PYTHONINSPECT, so basically we are telling the script that it's in the interactive mode. If you run the script you will find yourself in well known python shell (interactive). Our next step is to clear the terminal when script is runned and to make a custom prompt. For this example we will use [custom] as a prompt:

#!/usr/bin/env python

import sys
import os

#clear the terminal
os.system('clear')

#custom prompt
sys.ps1 = "[custom] "
os.environ['PYTHONINSPECT'] = 'True'

 

You will get this:

Now we have our custom prompt "in" python shell. Now let's give our prompt a color, let say red. Coloring text in terminal (python shell) is done with ANSI sequences. For example white color is "\033[0m" and the red is "\033[31m".

#!/usr/bin/env python

import sys
import os

#red color
r = "\033[31m"

#whie color
w = "\033[0m"

#clear the terminal
os.system('clear')

#custom prompt
sys.ps1 = r + "[custom] " + w
os.environ['PYTHONINSPECT'] = 'True'

We added the white color because we dont want for all the input text to be blue, also when you exit the shell the color remains. Colors can be useful for success/warining/error/info messages as well as other information. Finaly let's go to the module importing. Usualy module imports are done by import modulename, or from abc import xyz and all of the combinations of static importing. What we want is to be able to dynamically import modules that we created. For this example I have created a directory in my working directory called modules. For loading modules we will use imp module.

#!/usr/bin/env python

import sys
import os
import __builtin__
import imp

#red color
r = "\033[31m"

#white color
w = "\033[0m"

#clear the terminal
os.system('clear')

#custom prompt
sys.ps1 = r + "[custom] " + w

#load module
def _importmodule(module):
    try:
        modulename = "modules/" + module + ".py"
        ModuleFile = open(modulename, 'rb')
        mod =  imp.load_source(module, modulename, ModuleFile)

        #updating loaded module list
        __builtin__.__dict__.update(mod.__dict__)
        print w + "Module " + module + " loaded..."

        #adding [modulename] to prompt to see which module is currently loaded
        sys.ps1 = r + "[custom] " + "<" + module + "> " + w

    #closing opened file
    finally:
        try: ModuleFile.close()
        except: pass

#loading method
def loadmodule(mname):
    _importmodule(mname)

os.environ['PYTHONINSPECT'] = 'True'

I created a simple hello world module in modules directory called testmodule.py:

#!/usr/bin/env python

class testmodule(object):

    @staticmethod
    def hi():
        print "Hello World!"

This now looks like:

And we have succesfully loaded a module into our custom shell. Now you have a good fundation to build your own python shell framework and load your own custom modules into the framework. Something similar can be found in scapy (interactive packet manipulation program). To unload the module you can use something like:

def unloadmodule(moname):
    del sys.modules[moname]
    sys.ps1 = r +  "[custom] " + w

 

 

Comments are closed.

top Hackers For Charity