old_contents: import subprocess
  
  class ProcessOutput(object):
  
      def __init__(self, stdout, stderr, errorcode):
          self.stdout = stdout
          self.stderr = stderr
          self.errorcode = errorcode
  
      def getError(self):
          if self.errorcode != 0:
              return("Errorcode: %d\n%s" % (self.errorcode, self.stderr))
          return None
  
  def Popen(outdir, args):
      subp = subprocess.Popen([str(arg) for arg in args], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=outdir)
      output = subp.communicate()
      return ProcessOutput(output[0], output[1], subp.returncode) # 0 is stdout, 1 is stderr
new_contents: import subprocess
  
  class ProcessOutput(object):
  
      def __init__(self, stdout, stderr, errorcode):
          self.stdout = stdout
          self.stderr = stderr
          self.errorcode = errorcode
  
      def getError(self):
          if self.errorcode != 0:
              return("Errorcode: %d\n%s" % (self.errorcode, self.stderr))
          return None
  
  def Popen(outdir, args):
      subp = subprocess.Popen([str(arg) for arg in args], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=outdir)
      output = subp.communicate()
      return ProcessOutput(output[0], output[1], subp.returncode) # 0 is stdout, 1 is stderr
  
  
  def tee(*popenargs, **kwargs):
      """
      Run a command as if it were piped though tee.
  
      Output generated by the command is displayed in real time to the terminal.  
      It is also captured in strings and returned once the process terminated.  
      This function is very useful for logging output from cluster runs.  Naive 
      approaches like check_output() are vulnerable to crashes (i.e. if a job 
      exceeds its time limit) if they hold all output until the end.  This 
      function echos any output as soon as it's generated, so that the cluster 
      logging system will still work.
      """
  
      import subprocess, select, sys
  
      process = subprocess.Popen(
              stdout=subprocess.PIPE, stderr=subprocess.PIPE,
              *popenargs, **kwargs)
  
      stdout, stderr = '', ''
  
      def read_stream(input_callback, output_stream):   # (no fold)
          read = input_callback()
          output_stream.write(read)
          output_stream.flush()
          return read
  
      while process.poll() is None:
          watch = process.stdout.fileno(), process.stderr.fileno()
          ready = select.select(watch, [], [])[0]
  
          for fd in ready:
              if fd == process.stdout.fileno():
                  stdout += read_stream(process.stdout.readline, sys.stdout)
              if fd == process.stderr.fileno():
                  stderr += read_stream(process.stderr.readline, sys.stderr)
  
      stdout += read_stream(process.stdout.read, sys.stdout)
      stderr += read_stream(process.stderr.read, sys.stderr)
  
      return stdout, stderr
  
  def check_output(*popenargs, **kwargs):
      """ 
      Run command with arguments and return its output as a byte string.
  
      If the exit code was non-zero it raises a CalledProcessError.  The
      CalledProcessError object will have the return code in the returncode
      attribute and output in the output attribute.
  
      The arguments are the same as for the Popen constructor.  Example:
  
      >>> check_output(["ls", "-l", "/dev/null"])
      'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
  
      The stdout argument is not allowed as it is used internally.
      To capture standard error in the result, use stderr=STDOUT.
  
      >>> check_output(["/bin/sh", "-c",
      ...               "ls -l non_existent_file ; exit 0"],
      ...              stderr=STDOUT)
      'ls: non_existent_file: No such file or directory\n'
      """
  
      # Note: This function has been part of the python standard library since 
      # python27.  I included it here because I commonly find myself wanting it 
      # on the cluster, which runs python26.
  
      from subprocess import Popen, PIPE, CalledProcessError
      if 'stdout' in kwargs:
          raise ValueError('stdout argument not allowed, it will be overridden.')
      process = Popen(stdout=PIPE, *popenargs, **kwargs)
      output, unused_err = process.communicate()
      retcode = process.poll()
      if retcode:
          cmd = kwargs.get("args")
          if cmd is None:
              cmd = popenargs[0]
          raise CalledProcessError(retcode, cmd)
      return output
  
  
subject: Add check_output() and tee() to the process module.