Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: code.interact(local=locals()) where stdin/stdout are not available

In Python, the following code snippet will open an interactive shell upon execution.

import code; code.interact(local = locals())

This has proved tremendously useful for debugging in quite a bit of code that is poorly documented. One can use the shell to navigate the in-program environment and figure out what's going on, even without a debugger. So far, so good.

Now the challenge.

The software I'm using (which is written in Django, by the way) uses some sort of scheduling mechanism which then speaks to another Python process, to which I have no control over other than editing its code. I have no input to it other than the variables I send to it for processing.

However, I don't know how the code works since documentation is very poor, so I wanted to use the code.interact method to figure things out.

But this process is started somewhere in the background by some special scheduling software, so the flow does not go from the Django application to the portions I wish to examine. Instead, a signal and object are sent which are then run later, at an arbitrary time (anywhere between 10-200ms) in a completely different process. When the signal and object are received, stdin/stdout is out of the picture altogether.

So I figured that instead of using stdin/stdout to communicate with code.interact I could use a file handle or Unix socket by specifying the readfunc parameter. I've tried this by open()ing a file and socket, but to no avail.

Now I'm trying to get that to work merely from the Django process itself so even the scheduling problem is out of the question, and while the interactive shell indeed starts, it shuts down immediately, neither accepting a file with commands as content, nor a Unix socket to which Python commands are piped.

To make a long story short; is it possible to communicate with an interactive shell invoked by code.interact by some other means than stdin/stdout? If so, how?

Thanks in advance.

like image 844
Teekin Avatar asked Aug 10 '12 13:08

Teekin


1 Answers

I don't entirely follow the bit about the scheduler and django and whatever.

But to answer the core of your question:

#!/usr/bin/python

import code

f = open('input.txt', 'r')

def readfunc(prompt):
    return f.readline()

code.interact(readfunc=readfunc)

Then run that in one terminal:

$ ./test.py 
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)

Notice you don't get a prompt.

Then in another terminal run:

echo "globals()" >> input.txt

And back in the first terminal you'll see the output.

like image 166
mpe Avatar answered Oct 21 '22 17:10

mpe