Set timeout on a subprocess and capture live stdout

Viewed 65

I am running an external script via subprocess. This script generates its own logs which I need to print within my Python script. Here's how I'm doing it right now:

proc = subprocess.Popen(external_script, \
           stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

for line in proc.stdout:
    logger.info(f"{line}")

Now, this external script takes a while to complete, so I also want to set a timeout for it. However, the Popen constructor does not take a timeout argument. I could use Popen.communicate() with a timeout, but I do not know how to read the logs live using communicate(). I believe communicate() waits till the process is complete/timeout expires and then allows you to read stdout.

Is there a way to both: a) set a timeout AND b) read live stdout from the subprocess ?

1 Answers

Yes there is, but not directly using Popen. Use Timer class from threading

from threading import Timer
proc = subprocess.Popen(external_script, \
           stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

Timer(TIMEOUT,proc.terminate).start() # call proc.terminate() from another thread after TIMEOUT seconds

for line in proc.stdout:
    logger.info(f"{line}")
Related