File: tee.py

package info (click to toggle)
openmolcas 25.02-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 170,204 kB
  • sloc: f90: 498,088; fortran: 139,779; python: 13,587; ansic: 5,745; sh: 745; javascript: 660; pascal: 460; perl: 325; makefile: 17
file content (59 lines) | stat: -rw-r--r-- 2,478 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# -*- coding: utf-8 -*-

#***********************************************************************
# This file is part of OpenMolcas.                                     *
#                                                                      *
# OpenMolcas is free software; you can redistribute it and/or modify   *
# it under the terms of the GNU Lesser General Public License, v. 2.1. *
# OpenMolcas is distributed in the hope that it will be useful, but it *
# is provided "as is" and without any express or implied warranties.   *
# For more details see the full text of the license in the file        *
# LICENSE or in <http://www.gnu.org/licenses/>.                        *
#***********************************************************************

#***********************************************************************
# This file is based on code posted by J.F. Sebastian on stackoverflow *
# (https://stackoverflow.com/a/4985080)                                *
# and licensed under CC-BY-SA 3.0                                      *
# (https://creativecommons.org/licenses/by-sa/3.0)                     *
#***********************************************************************

from __future__ import (unicode_literals, division, absolute_import, print_function)

import sys
from subprocess import Popen, PIPE
from threading import Thread

def tee(infile, *files):
  '''Print "infile" to "files" in a separate thread.'''
  def fanout(infile, *files):
    # Write each input line in all the files,
    # Try as a byte string first, then as utf8
    for line in iter(infile.readline, b''):
      for f in files:
        try:
          f.write(line)
        except TypeError:
          f.write(line.decode('utf-8', 'replace'))
    infile.close()
  t = Thread(target=fanout, args=(infile,)+files)
  t.daemon = True
  t.start()
  return t

def teed_call(cmd_args, **kwargs):
  stdout, stderr = [kwargs.pop(s, None) for s in ['stdout', 'stderr']]
  no_tee = kwargs.pop('no_tee', False)
  if (no_tee):
    p = Popen(cmd_args, stdout=sys.stdout, stderr=sys.stderr, **kwargs)
  else:
    p = Popen(cmd_args,
            stdout=PIPE if stdout is not None else None,
            stderr=PIPE if stderr is not None else None,
            **kwargs)
    threads = []
    if stdout is not None: threads.append(tee(p.stdout, stdout, sys.stdout))
    if stderr is not None: threads.append(tee(p.stderr, stderr, sys.stderr))
    for t in threads:
      t.join()
  return p.wait()