subprocess.Popen() output to logging.StreamHandler()
Thomas Dimson
tdimson at gmail.com
Thu Apr 10 09:59:09 EDT 2008
On Apr 10, 8:11 am, "sven _" <svens... at gmail.com> wrote:
> Version: Python 2.5.1 (r251:54863, Mar 7 2008, 04:10:12)
>
> My goal is to have stdout and stderr written to a logging handler.
> This code does not work:
>
> # START
> import logging, subprocess
> ch = logging.StreamHandler()
> ch.setLevel(logging.DEBUG)
> subprocess.call(['ls', '-la'], 0, None, None, ch, ch)
> # END
>
> Traceback (most recent call last):
> File "log.py", line 5, in <module>
> subprocess.call(['ls', '-la'], 0, None, None, ch, ch)
> File "/usr/lib/python2.5/subprocess.py", line 443, in call
> return Popen(*popenargs, **kwargs).wait()
> File "/usr/lib/python2.5/subprocess.py", line 586, in __init__
> errread, errwrite) = self._get_handles(stdin, stdout, stderr)
> File "/usr/lib/python2.5/subprocess.py", line 941, in _get_handles
> c2pwrite = stdout.fileno()
> AttributeError: StreamHandler instance has no attribute 'fileno'
>
> This is because subprocess.Popen() expects file descriptors to write
> to, and logging.StreamHandler() does not supply it. The StreamHandler
> could supply its own stdout file descriptor, but then Popen() would
> write directly to that file, bypassing all the logging fluff.
>
> A possible solution would be to make a named pipe (os.mkfifo()), have
> Popen() write to that, and then have some horrendous hack run select()
> or similar on the fifo to read from it and finally pass it to
> StreamHandler.
>
> Are there better solutions?
>
> sven
What is wrong with doing something like:
import logging, subprocess
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
s = subprocess.Popen( ['ls','-la'], stdout=subprocess.PIPE )
while 1:
ch.info( s.stdout.readline() )
if s.poll() == None:
break
Perhaps not the most efficient or clean solution, but that is how I
usually do it (note: I didn't test the above code).
-Thomas Dimson
More information about the Python-list
mailing list