Reputation:
There are countless amount of questions here about how to read from stderr and stdout of a subprocess. Is it possible to do so with the current process's stderr? I checked it and it raised an IO Error : File not open for reading.
I needed to read the stderr and get the data for further processing. Are there any ways to open the file in 'r+' mode?
One way I thought of was to override the default sys.stderr with a class like:
class CustomStdErr(object):
def write(self, data):
with open(fakestderr, 'r+') as f:
f.write(data)
sys.stderr = CustomStdErr()
Are there any other ways to do it more directly?
EDIT: Why I need the stderr:
There is a thread (call it X) in the code that interacts with the main thread (call it M). The main thread has logging enabled. This is redirected to the stderr. Now, thread X's duty is to monitor stderr and read from it and process that for the main thread. This is, in summary, what's happening.
Upvotes: 2
Views: 6476
Reputation: 2909
If you're on *ix and you have an interactive process, you can open('/dev/tty', 'r'). This is similar to reading from stderr. Note that open('/dev/tty", 'r+') only works in 2.x; in 3.x you need open('/dev/tty', 'r').
Upvotes: 1
Reputation: 148900
Well you cannot directly do what you want. If one thread writes to the default sys.stderr
, by default it will go to the terminal, and it will be impossible to another thread to read that.
But ... you can always change sys.stderr
to any object that has a write
method taking a string argument (extract from the doc of the Standard Python Library sys
module : stderr
needn’t be built-in file objects: any object is acceptable as long as it has a write()
method that takes a string argument. (Changing these objects doesn’t affect the standard I/O streams of processes executed by os.popen()
, os.system()
or the exec*()
family of functions in the os module.))
In short : if you thread directly writes to sys.stderr
, you could create a pair of pipes with os.pipe()
affect the write end to sys.stderr
, read the read end from the monitoring thread - than can still write to sys.__sterr__
or to a saved value of sys.stderr
If you thread launches subprocesses, do use a subprocess.Popen
object to redirect the stderr stream of the subcommand to a pipe and read it from your monitoring thread.
Upvotes: 2