title: How to seamlessly wrap Bash shell IO in Python
body: <p>How do you wrap a bash shell session in a Python script so that Python can store the stdout and stderr to a database, and occasionally write to stdin?</p>
  
  <p>I tried using subprocess with a tee-like Python class to redirect the IO, but it seems to use fileno to bypass Python entirely.</p>
  
  <p>shell.py:</p>
  
  <pre><code>import os
  import sys
  from StringIO import StringIO
  from subprocess import Popen, PIPE
  
  class TeeFile(StringIO):
      def __init__(self, file, auto_flush=False):
          #super(TeeFile, self).__init__()
          StringIO.__init__(self)
          self.file = file
          self.auto_flush = auto_flush
          self.length = 0
  
      def write(self, s):
          print 'writing' # This is never called!!!
          self.length += len(s)
          self.file.write(s)
          #super(TeeFile, self).write(s)
          StringIO.write(self, s)
          if self.auto_flush:
              self.file.flush()
  
      def flush(self):
          self.file.flush()
          StringIO.flush(self)
  
      def fileno(self):
          return self.file.fileno()
  
  cmd = ' '.join(sys.argv[1:])
  stderr = TeeFile(sys.stderr, True)
  stdout = TeeFile(sys.stdout, True)
  
  p = Popen(cmd, shell=True, stdin=PIPE, stdout=stdout, stderr=stderr, close_fds=True)
  </code></pre>
  
  <p>e.g. Running <code>python shell.py ping google.com</code> runs the correct command and shows output, but Python never sees the stdout.</p>