4

Using the subprocess module (Python 2.7), I'm running a command and attempting to process its output as it runs.

I have code like the following:

process = subprocess.Popen(
    ['udevadm', 'monitor', '--subsystem=usb', '--property'],
    stdout=subprocess.PIPE)
for line in iter(process.stdout.readline, ''):
    print(line)

However, the output only gets printed after I Ctrl+C, even if I add sys.stdout.flush() after the print statement.

Why is this happening, and how can I live stream the output from this process?

Notably, this udevadm monitor command is not intended to terminate, so I can't simply wait for the process to terminate and process its output all at once.

I found live output from subprocess command but the approach in the accepted answer did not solve my problem.

Community
  • 1
  • 1
Brandon Duffany
  • 944
  • 3
  • 7
  • 26
  • see [the links in the paragraph that starts with: "If subprocess' stdout uses a block buffering"](http://stackoverflow.com/a/17698359/4279) – jfs Apr 27 '16 at 14:50

1 Answers1

4

You could use unbuffer :

process = subprocess.Popen(
    ["unbuffer", 'udevadm', 'monitor', '--subsystem=usb', '--property'],
    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in iter(process.stdout.readline, ''):
    print(line)
Padraic Cunningham
  • 160,756
  • 20
  • 201
  • 286
  • Thanks! This works. But is there a way to do this with only Python? I'd prefer to avoid the `expect` dependency. – Brandon Duffany Apr 26 '16 at 21:53
  • Unfortunately I cannot see a way but that certainly does not mean that there is not, I do see some output if I disconnect and reconnect something to the use port but in chunks more than line buffered and still a decent delay between output – Padraic Cunningham Apr 26 '16 at 22:13