How to redirect stdout to screen and at the same time save to a variable
<p>I am trying to redirect stdout to screen and at the same time save to a variable and running into error <code>AttributeError: __exit__</code> at line <code>with proc.stdout:</code>,can anyone tell me how to accomplish this?</p>

<pre><code>...............
proc = subprocess.Popen(cmd.split(' '), stderr=subprocess.PIPE)
try:
    proc.wait(timeout=time_out) 
except TimeoutExpired as e:
    print e
    proc.kill()
with proc.stdout:
    for line in proc.stdout:
        print line
</code></pre>

<p>Error:-</p>

<pre><code>    with proc.stdout:
AttributeError: __exit__
</code></pre>

<p><strong>UPDATE:-</strong></p>

<pre><code>proc = subprocess.Popen(cmd.split(' '),stdout=subprocess.PIPE )
print "Executing %s"%cmd
try:
    proc.wait(timeout=time_out)//HUNG here until timeout kicks-in
except TimeoutExpired as e:
    print e
    proc.kill()
with proc.stdout as stdout:
    for line in stdout:
        print line,
</code></pre>

<p>Once you make <code>stdout</code> a <code>PIPE</code> you can just create a loop that reads the pipe and writes it to as many places as you want. Dealing with <code>stderr</code> makes the situation a little trickier because you need a background reader for it also. So, create a thread and a utility that writes to multiple files and you are done.</p>

<pre><code>import sys
import threading
from StringIO import StringIO
import subprocess as subp
import shlex

def _file_copy_many(fp, *write_to):
    """Copy from one file object to one or more file objects"""
    while True:
        buf = fp.read(65536)
        if not buf:
            return
        for fp in write_to:
            fp.write(buf)

# for test
cmd = "ls -l"

# will hold stdout and stderr
outbuf = StringIO()
errbuf = StringIO()

# run the command and close its stdin
proc = subp.Popen(shlex.split(cmd), stdin=subp.PIPE, stdout=subp.PIPE, 
    stderr=subp.PIPE)
proc.stdin.close()

# background thread to write stderr to buffer
stderr_thread = threading.Thread(target=_file_copy_many, 
    args=(proc.stderr, errbuf))
stderr_thread.start()

# write stdout to screen and buffer then wait for program completion
_file_copy_many(proc.stdout, sys.stdout, outbuf)
return_code = proc.wait()

# wait for err thread
stderr_thread.join()

# use buffers
print outbuf.tell(), errbuf.tell()
outbuf.seek(0)
errbuf.seek(0)
</code></pre>

<p>This is similar to what <code>subprocess.Popen.communicate</code> does but writes to more destinations.</p>

python