code: def run(self, args):
          
  
          # run a subprocess and put the stdout and stderr on the pipe object
          try:
              pipe = subprocess.Popen(
                  args,
                  stdout=subprocess.PIPE, stderr=subprocess.PIPE,
              )
          except OSError as e:
              if e.errno == errno.ENOENT:
                  # File not found.
                  # This is equivalent to getting exitcode 127 from sh
                  raise exceptions.ShellError(
                      ' '.join(args), 127, '', '',
                  )
  
          # pipe.wait() ends up hanging on large files. using
          # pipe.communicate appears to avoid this issue
          stdout, stderr = pipe.communicate()
  
          # if pipe is busted, raise an error (unlike Fabric)
          if pipe.returncode != 0:
              raise exceptions.ShellError(
                  ' '.join(args), pipe.returncode, stdout, stderr,
              )
  
          return stdout, stderr
docs: Run ``command`` and return the subsequent ``stdout`` and ``stderr``
          as a tuple. If the command is not successful, this raises a
          :exc:`textract.exceptions.ShellError`.