Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python use timeout for subprocess with Popen

Im running the following script with popen

process = subprocess.Popen(['python', 'solver.py', 'newsudoku.csp', '-i', 'arc'], stdout=subprocess.PIPE)
out, err = process.communicate()

I need to process the output that is being stored in the out variable

thing is this script varies in the time of its execution, and I need to kill it if it goes past 60 seconds. I know that python 3 has timeout for check_call, but the other script im running is in python 2.7

So how could I count 60 seconds and then kill the subprocess? ideally doing something else as well if this happens (adding 1 to a counter)

like image 648
user3713929 Avatar asked Apr 27 '15 02:04

user3713929


People also ask

How do I stop subprocess Popen?

subprocess. Popen. kill(proc) is exactly the same as proc. kill() FYI.

How do I use subprocess Popen in Python?

To start a new process, or in other words, a new subprocess in Python, you need to use the Popen function call. It is possible to pass two parameters in the function call. The first parameter is the program you want to start, and the second is the file argument.

Does subprocess Popen block?

Popen is nonblocking. call and check_call are blocking. You can make the Popen instance block by calling its wait or communicate method.


2 Answers

You can use the timeout or waitmax commands to set a time limit on the process you are running with Popen. For instance, to run a tail -f command for a maximum of 10 seconds -

import subprocess
process=subprocess.Popen(['timeout' ,'10', 'tail', '-f', '/var/log/syslog'], stdout=subprocess.PIPE)
out,err = process.communicate()

print out
Apr 26 21:40:01 linubuvma CRON[49447]: (smmsp) CMD (test -x /etc/init.d/sendmail && /usr/share/sendmail/sendmail cron-msp)
Apr 26 21:45:01 linubuvma CRON[50065]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Apr 26 21:55:01 linubuvma CRON[51271]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Apr 26 22:00:01 linubuvma CRON[51871]: (smmsp) CMD (test -x /etc/init.d/sendmail && /usr/share/sendmail/sendmail cron-msp)
Apr 26 22:05:01 linubuvma CRON[52491]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Apr 26 22:09:01 linubuvma CRON[52975]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -x /usr/lib/php5/sessionclean ] && [ -d /var/lib/php5 ] && /usr/lib/php5/sessionclean /var/lib/php5 $(/usr/lib/php5/maxlifetime))
Apr 26 22:15:01 linubuvma CRON[53707]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Apr 26 22:17:01 linubuvma CRON[53951]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Apr 26 22:20:01 linubuvma CRON[54311]: (smmsp) CMD (test -x /etc/init.d/sendmail && /usr/share/sendmail/sendmail cron-msp)
Apr 26 22:25:01 linubuvma CRON[54937]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)

The tail commands terminated exactly after 10 seconds.

like image 142
Daniel t. Avatar answered Oct 30 '22 05:10

Daniel t.


you can also do something like this in python 3.7.4:

p1 = subprocess.Popen(['python', 'solver.py', 'newsudoku.csp', '-i', 'arc'], stderr = subprocess.PIPE) 
    try:
        outs, errs = p1.communicate(timeout=60) # will raise error and kill any process that runs longer than 60 seconds
    except subprocess.TimeoutExpired as e:
        p1.kill()
        outs, errs = p1.communicate()
        print(outs)
        print(errs)
like image 27
momaji Avatar answered Oct 30 '22 04:10

momaji