10

I have the following Python code:

strRunOutput = subprocess.run([strFastbootExecutable, "-s", dsn.upper(), "reboot"], timeout=5, stderr=subprocess.PIPE).stderr.decode('utf-8').upper()

Which is essentially doing this:

fastboot -s G070GV1871970FCW reboot

and this is the output:

< waiting for G070GV1871970FCW >

...which is hanging. Why the fastboot command is hanging, I don't know, but what bothers me more is that the subprocess.run command isn't timing out after 5 seconds as I told it to and is causing my program to hang. Any ideas what's going on?

Thanks!

Mike
  • 504
  • 7
  • 23

2 Answers2

8

This is a known issue - there are two tickets on the Python bug tracker relating to it.

It's not timing out because you connected a pipe.

Issue31935: subprocess.run() timeout not working with grandchildren and stdout=PIPE
Issue30154: subprocess.run with stderr connected to a pipe won't timeout when killing a never-ending shell commanad (sic)

Alan
  • 2,914
  • 2
  • 14
  • 26
  • 1
    Ugh, this is frustrating! Would you happen to know of any workarounds for this. I really need to capture the output of my program but if it hangs, it stops everything else from working. I will definitely post something on the appropriate links that you provided. Thanks! – Mike May 15 '18 at 17:12
  • If you wrap `strFastbootExecutable` in a bash/powershell script that writes the output to a text file, you can skip the pipe since output is independent. – Alan May 15 '18 at 18:30
  • Hmm..... Lemme play with that. It seems like I'm still getting hung up even without the pipe, but I'm not totally sure because it's only on certain test lab computers that this is happening when an Android device gets stuck in some weird configuration, and my coworker "unstuck" the problem device so I can't run this against that anymore. But I'll keep at it and see if I can get replicate the behavior and then see about implementing your suggestion. Thanks for the idea! – Mike May 16 '18 at 03:31
  • If you're feeling daring, you can try going multithreaded (which is what I'd do in non-python languages). See this answer for how to use multiprocessing: https://stackoverflow.com/questions/14920384/stop-code-after-time-period – Alan May 16 '18 at 12:42
0

The problem is because of the pipes. However, the following worked for me even with pipes:

proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
try:
  return proc.communicate(timeout=1.0)
except TimeoutExpired:
  proc.kill()
  return proc.communicate()

Source: https://github.com/python/cpython/issues/81605

Alwin
  • 786
  • 9
  • 19