code: def shell(command, **kwargs):
      
      b_stdoutflush       = False
      b_stderrflush       = False
      b_waitForChild      = True
      for key, val in kwargs.items():
          if key == 'stdoutflush':        b_stdoutflush   = val
          if key == 'stderrflush':        b_stderrflush   = val
          if key == 'waitForChild':       b_waitForChild  = val
      child = popen2.Popen3(command, 1) # capture stdout and stderr from command
      child.tochild.close()             # don't need to talk to child
      outfile = child.fromchild
      outfd = outfile.fileno()
      errfile = child.childerr
      errfd = errfile.fileno()
      makeNonBlocking(outfd)            # don't deadlock!
      makeNonBlocking(errfd)
      outdata = errdata = ''
      outeof = erreof = 0
      while b_waitForChild:
          ready = select.select([outfd,errfd],[],[]) # wait for input
          if outfd in ready[0]:
              outchunk = outfile.read()
              if b_stdoutflush: sys.stdout.write(outchunk)
              if outchunk == '': outeof = 1
              outdata = outdata + outchunk
          if errfd in ready[0]:
              errchunk = errfile.read()
              if b_stderrflush: sys.stderr.write(errchunk)
              if errchunk == '': erreof = 1
              errdata = errdata + errchunk
          if outeof and erreof: break
          select.select([],[],[],.1) # give a little time for buffers to fill
      err = child.wait()
      return outdata, errdata, err
docs: Runs 'command' on the underlying shell and keeps the stdout and
          stderr stream separate.
  
          Returns [stdout, stderr, exitCode]