Skip to content

Instantly share code, notes, and snippets.

@kirpit
Last active March 17, 2023 06:29
Show Gist options
  • Save kirpit/1306188 to your computer and use it in GitHub Desktop.
Save kirpit/1306188 to your computer and use it in GitHub Desktop.
Enables to run subprocess commands in a different thread with TIMEOUT option!
#! /usr/bin/env python
import threading
import subprocess
import traceback
import shlex
class Command(object):
"""
Enables to run subprocess commands in a different thread with TIMEOUT option.
Based on jcollado's solution:
http://stackoverflow.com/questions/1191374/subprocess-with-timeout/4825933#4825933
"""
command = None
process = None
status = None
output, error = '', ''
def __init__(self, command):
if isinstance(command, basestring):
command = shlex.split(command)
self.command = command
def run(self, timeout=None, **kwargs):
""" Run a command then return: (status, output, error). """
def target(**kwargs):
try:
self.process = subprocess.Popen(self.command, **kwargs)
self.output, self.error = self.process.communicate()
self.status = self.process.returncode
except:
self.error = traceback.format_exc()
self.status = -1
# default stdout and stderr
if 'stdout' not in kwargs:
kwargs['stdout'] = subprocess.PIPE
if 'stderr' not in kwargs:
kwargs['stderr'] = subprocess.PIPE
# thread
thread = threading.Thread(target=target, kwargs=kwargs)
thread.start()
thread.join(timeout)
if thread.is_alive():
self.process.terminate()
thread.join()
return self.status, self.output, self.error
@alevchuk
Copy link

I get:

Traceback (most recent call last):
File "./subprocess_timeout.py", line 34, in
command.run(timeout=3)
File "./subprocess_timeout.py", line 31, in run
return self.process.returncode
AttributeError: 'NoneType' object has no attribute 'returncode'

@ogasser
Copy link

ogasser commented Aug 31, 2012

Pass shell=True if you want Popen to execute the program in a shell. Beware of maclicious input though!

Example:

command = Command("echo 'Process started'; sleep 2; echo 'Process finished'")
command.run(timeout=1, shell=True)

@kunzhipeng
Copy link

command = Command('ping www.redicecn.com -t')
print command.run(timeout=1, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True)

Not work on Window7, Python 2.7.

@kirpit
Copy link
Author

kirpit commented Dec 29, 2012

all these complains should be satisfied now with the latest revision.

it should also be able to run commands even though no shell=True argument provided, which is done by shlex splitting..

@davidyoung8906
Copy link

I use the cmd to start a java program. I find that the thread will keep running after thread.join()

@sunway1988
Copy link

Now we can use timeout in Ubuntu 10.04 and later versions happily.

@onkar27
Copy link

onkar27 commented Jul 3, 2017

Solution.java is

class Solution{
      public static void main(String [] args){ 
              do
                    System.out.println("Helloo");
              while(true);
      }
}

and

command = Command("java Solution")
print command.run(timeout=1, shell=True ,stderr=subprocess.STDOUT, stdout=subprocess.PIPE)

Timeout does not works !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment