简体   繁体   中英

Python 3 subprocess module - return console output after timeout hit

I have the below code that kicks off an executable and waits for the response from the shell once it completes execution. I have timeout set of 60 seconds. If the executable finishes it's work within 60 seconds, the variable streamdata is a string of what would be printed to the console screen if you ran the executable interactively.

However, if the timeout cut off is reached, the value of streamdata just seems to be a blank binary string. How can I amend so that I still get the STDOUT after timeout has killed the.exe?

startupinfo = None
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            
process = subprocess.Popen([<parameters>], stdout=subprocess.PIPE, startupinfo=startupinfo)
process2 = process.pid
streamdata = process.communicate(timeout=60)[0]
streamdata2 = streamdata.decode(errors='replace')
rc = process.returncode

Let subprocess redirect stdout to a file(or something),then read it. For example:

import subprocess
import os
program_path="E:/Project2.exe"
file_path="E:/1.txt"
if os.path.exists(file_path):
    os.remove(file_path)

startupinfo = None
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
with open(file_path,'w') as f:
    process = subprocess.Popen([program_path],stdout=f, startupinfo = startupinfo)
process2 = process.pid
try:
    streamdata = process.communicate(timeout=2)[0]
except Exception:
    print("Time Out!")
    with open(file_path, 'r') as f:
        print(f.readlines())
    process.kill()

Output:

Time Out!
['1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n', '1\n']

If you want to get as much output as possible, flush stdout more frequently in subprocess.

If you only need to see the output in console:

startupinfo = None
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            
process = subprocess.Popen([<parameters>],startupinfo=startupinfo)#<-here is the difference
process2 = process.pid
streamdata = process.communicate(timeout=60)[0]
streamdata2 = streamdata.decode(errors='replace')
rc = process.returncode

Op's answer did not work. However after an afternoon of messing around I have finally got the below to work. Couldn't really find any comparable answers on SO, however my solution is based almost entirely on the example given in the subprocess docs, so lesson learned is don't always rely on here and consult the docs before you post!

try:
            
    startupinfo = None
    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        
    process = subprocess.Popen([<parameters>], stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo)
    process2 = process.pid

    outs, errs = process.communicate(timeout=5)
    print(outs)

except subprocess.TimeoutExpired:

    process.kill()
    outs, errs = process.communicate(timeout=6)
    print(outs)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM