Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python subprocess.call with timeout retry

I want to re-run subprocess.call if it's timeout somehow.

subprocess.call('some command', timeout=600)
if timeout:
    subprocess.call('some command')

How do i do something like this?

like image 206
ggnoredo Avatar asked Jan 21 '19 11:01

ggnoredo


2 Answers

subprocess.call raises [Python 3.Docs]: exception subprocess.TimeoutExpired when timeout is (given and) reached (just like Popen.communicate).

Here's a piece of code that keeps launching NotePad with a timeout of 3 seconds, until it runs 2 times, or user manually closes it:

>>> max_runs = 2
>>> run = 0
>>> while run < max_runs:
...     try:
...             subprocess.call("notepad", timeout=3)
...     except subprocess.TimeoutExpired:
...             continue
...     else:
...             break
...     finally:
...             run += 1
...
0

Although this technically answers the question, I don't think it's a good idea to re-launch a process that didn't end, since there's a great chance that the consecutive runs will have the same outcome (will timeout). In that case, you'd have to use Popen and communicate, and if the process times out, kill it via Popen.terminate.

like image 94
CristiFati Avatar answered Oct 07 '22 20:10

CristiFati


You can use basic error handling to do catch the timeout exception:

try:
    subprocess.call('cmd', timeout=0)
except subprocess.TimeoutExpired:
    print('Expired!')
    # subprocess.call('cmd')

The except block is only run if the specified error is raised. See Python docs tutorial on exceptions, specifically error handling for more information.

like image 36
Felix Avatar answered Oct 07 '22 20:10

Felix