2

I want something like this run the 'ls' command and output on STDOUT and want to store same output in variable

For long running process I need to see the executing output on screen and also at last capture on variable

proc = subprocess.Popen(["ls"], stdout=subprocess.PIPE, shell=False)
(out, err) = proc.communicate()
print "program output:-", out

here the output coming after execution

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • try `proc.stdout.read(1)` in a loop. instead of communicate. – User Jun 12 '13 at 12:53
  • @mnagel: you could reuse my answer from [Python subprocess get children's output to file and terminal?](http://stackoverflow.com/questions/4984428/python-subprocess-get-childrens-output-to-file-and-terminal) question by providing `f = io.BytesIO()` object as a file-like object to the `teed_call(..., stdout=f)` function and obtaining the output later as `out = f.getvalue()`. – jfs Sep 08 '13 at 17:56

1 Answers1

1

To print output line-by-line as soon as child processes flushes its stdout and to store it in a variable:

from subprocess import Popen, PIPE

buf = []
proc = Popen([cmd], stdout=PIPE, bufsize=1)
for line in iter(proc.stdout.readline, b''):
    buf.append(line)
    print line,
proc.communicate() # close `proc.stdout`; wait for the child process to exit
output = b"".join(buf)

There could be a buffering issue (the output appears with a delay); to fix it, you could use pexpect, pty modules or stdbuf, unbuffer, script commands.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • thank you! this looks promising. i think it should be `print(line.rstrip('\n'))` or you get superfluous blank lines. why is there a comma after that line? also, is it possible to grab stderr as well? – mnagel Sep 08 '13 at 20:55
  • @mnagel: there won't be superfluous blank lines, that is why the comma is there. It is kind-of a hack, read about `sys.stdout.softspace`. To grab `stderr` as well, you could set it as `stderr=STDOUT` or if you want stdout/stderr to be separate then [use `teed_call(..., stdout=f, stderr=g); out = f.getvalue(); err = g.getvalue()` mentioned in my comment](http://stackoverflow.com/questions/17065043/subprocess-or-commands-getstatusoutput-in-stdout-and-store-at-variable/18686982?noredirect=1#comment27526627_17065043) – jfs Sep 09 '13 at 01:19
  • @j-f-sebastian: i think the issue with the blank lines is related to my use of `from __future__ import print_function`. and i am not totally happy with the handling of stderr, but this solved my immediate problem, so i will reward the bounty. thanks! – mnagel Sep 12 '13 at 18:37