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