def drain_pipes(popen_list, ignore_stderr=False):
  """ Read the output from piped output (see exec_binaries() above)
  :param pipes: list of Popen objects
  :return:  A list of strings Output from the subprocesses. Output from pipes is
          not interleaved.  Blocks until all output is drained.
  """
  results=[]
  for p in popen_list:
    # Originally this code tried to work as a generator, returning output as it was returned from
    # the spawned task by reading lines from the pipes, but that lead to deadlocks, just as
    # predicted by the python docs.  To work that way reliably you have to use select(), threads, or
    # separate proceses.
    (stdoutdata, stderrdata) = p.communicate()
    streams_from_task = [stdoutdata]
    if not ignore_stderr:
     streams_from_task.append(stderrdata)
    for data in streams_from_task:
      if data:
        for line in data.split('\n'):
          results.append(line)
  return results