user1601716
user1601716

Reputation: 1993

subprocess not returning until command complete

I am trying to get a real time output from a bash command so i can play with the data easier.

In this code, the command iostat 1 works fine and prints output at 1 second. The command sar -u 1 20, which runs as expected on the command line (printing 1 line every second up to 20), waits until the command is complete ~20 seconds, before printing each line with a .1 second delay.

I am planning on running these commands indefinitely, and need this part to work. Any thoughts on whats wrong? I am on OSX.

import subprocess
import time

# run a command and constantly check for new output, if you find it, print it and continue
# if the command is done, break out
try:
    command="sar -u 1 20"
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    while True:
        time.sleep(.1) # so i don't kill the cpu on the machine i'm checking
        output = process.stdout.readline()
        #if process.poll() is not None:
        #    break
        if output:
            print output.strip()
except KeyboardInterrupt:
    print 'Exiting...'
return_code = process.poll()
print return_code

Upvotes: 1

Views: 234

Answers (2)

chepner
chepner

Reputation: 531055

sar detects that its standard output is not a terminal and buffers its output. It doesn't produce much output, so the buffer does not fill up enough to be flushed to the pipe before it times out.

If you install GNU coreutils, you can use the stdbuf command to disable buffering for standard output. (If you install it via Homebrew, it is installed as gstdbuf.)

command = "stdbuf -o 0 sar -u 1 20"

I'm not sure if there is a comparable solution using tools included with Mac OS X.

Upvotes: 1

Corey Goldberg
Corey Goldberg

Reputation: 60604

from: https://stackoverflow.com/a/17698359/16148

for Python 2:

from subprocess import Popen, PIPE

p = Popen(["cmd", "arg1"], stdout=PIPE, bufsize=1)
with p.stdout:
    for line in iter(p.stdout.readline, b''):
        print line,
p.wait() # wait for the subprocess to exit

Upvotes: 0

Related Questions