3

To get an output of a command we could do this

os.popen("ls").read()

But suppose I have a command that I don't want to wait for it to return. In fact, I want to keep it running, and occasionally spit out some output. (Eg., java PrintEvery5) (Suppose the PrintEvery5 would print a line every 5 seconds).

How do subscribe to the process/thread and grab the output of this?

I've tried the following, which didn't seem to work.

### file: deqthread.py
import threading, os, subprocess

class DeqThread(threading.Thread):
     def __init__(self):
         super(DeqThread, self).__init__()
         self.f=os.popen("java PrintEvery5")

     def run(self):
         print("in run")

     def readResult(self):
         return self.f.read() 


thread1 = DeqThread()
thread1.start()                                                                                                         

while True:

    print(thread1.readResult())

Running python deqthread.py, I don't see any output. THe whole thing just hangs there.

When I try this, I could see the output. (ie., it keeps printing to the console),

$python <ENTER>
>>> import os
>>> os.system("java PrintEvery5")

So what do I need to change in my deqthread.py file so that I can get output out of my command?

roippi
  • 25,533
  • 4
  • 48
  • 73
One Two Three
  • 22,327
  • 24
  • 73
  • 114

2 Answers2

0

Have you tried using the the check_output method in subprocess module? It allows you to run a command with arguments and return its output as a byte string.

import subprocess

output = subprocess.check_output(["echo", "Hello Java!"])
print output

So __init__ could become:

def __init__(self):
     super(DeqThread, self).__init__()

And readResult could become:

def readResult(self):
     def readResult(self):
         output = subprocess.check_output(["echo", "Hello Java!"])
         return output 

See documentation here: https://docs.python.org/2/library/subprocess.html

alex
  • 602
  • 4
  • 7
  • No, I didn't even know what to look for. Thanks for the suggestion! (This is where one gets to say "you don't know what you don't know!" :) ) – One Two Three May 14 '14 at 04:36
  • 3
    That still blocks until the call returns. – roippi May 14 '14 at 04:36
  • try removing `self.f=os.popen("java PrintEvery5")` from `__int__` and place `output = subprocess.check_output(["echo", "Hello Java!"]) return output` in `readResult`. I just ran it on my machine and its working. See the edit. – alex May 14 '14 at 04:43
  • It works because `echo` returns in nanoseconds. The issue the OP is trying to solve is to capture stdout from a long-running process before it finishes. – roippi May 14 '14 at 04:56
  • here's another thread about intercepting stdout from a subprocess http://stackoverflow.com/questions/4417546/constantly-print-subprocess-output-while-process-is-running maybe that'll help – alex May 14 '14 at 05:00
0

Use subprocess.Popen(), then redirect stdout to subprocess.PIPE. Finally, get the output from the stdout member of sub-process instance. The example shows as below:

foo.py:

import time

count = 5
while count > 0:
    print 'Hello'
    count -= 1
    time.sleep(1)

main.py:

import subprocess

p = subprocess.Popen(['python.exe', 'foo.py'],
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)
for line in iter(p.stdout.readline, ''):
    print("OUTPUT: " + line.rstrip())
fred.yu
  • 865
  • 7
  • 10