code: def run(self, timeout=None, **kwargs):
          
          from subprocess import Popen, PIPE
  
          def target(**kw):
              try:
                  # print('Thread started')
                  self.process = Popen(self.command, **kw)
                  self.output, self.error = self.process.communicate()
                  self.retcode = self.process.returncode
                  # print('Thread stopped')
              except:
                  import traceback
                  self.error = traceback.format_exc()
                  self.retcode = -1
  
          # default stdout and stderr
          if 'stdout' not in kwargs:
              kwargs['stdout'] = PIPE
  
          if 'stderr' not in kwargs:
              kwargs['stderr'] = PIPE
  
          # thread
          import threading
          thread = threading.Thread(target=target, kwargs=kwargs)
          thread.start()
          thread.join(timeout)
  
          if thread.is_alive():
              # print("Terminating process")
              self.process.terminate()
              self.killed = True
              thread.join()
  
          return self
docs: Run a command in a separated thread and wait timeout seconds.
          kwargs are keyword arguments passed to Popen.
  
          Return: self