Skip to content

Instantly share code, notes, and snippets.

@danielrichman
Created January 2, 2012 14:31
Show Gist options
  • Save danielrichman/1550888 to your computer and use it in GitHub Desktop.
Save danielrichman/1550888 to your computer and use it in GitHub Desktop.
bidirectional tee
#!/usr/bin/python
import sys
import subprocess
import threading
import signal
if len(sys.argv) < 3:
sys.stderr.write("Usage: {0} output_file command [arg [arg] ...]\n"\
.format(sys.argv[0]))
sys.exit(1)
name = sys.argv[0]
filename = sys.argv[1]
command = sys.argv[2:]
l = open(filename, "a")
m = threading.Lock()
p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, bufsize=1)
l.write("{0} -- started {1}\n".format(p.pid, repr(command)))
def t(pfrom, pto, name):
while True:
line = pfrom.readline()
if not line:
break
pto.write(line)
pto.flush()
with m:
l.write(str(p.pid) + " " + name + " " + line)
if pto == p.stdin:
pto.close()
def s(*args):
with m:
l.write("{0} -- SIGINT\n".format(p.pid))
p.send_signal(signal.SIGINT)
signal.signal(signal.SIGINT, s)
thr_in = threading.Thread(target=t, args=(sys.stdin, p.stdin, ">>"))
thr_out = threading.Thread(target=t, args=(p.stdout, sys.stdout, "<<"))
thr_err = threading.Thread(target=t, args=(p.stderr, sys.stderr, "!!"))
thr_in.daemon = True
thr_in.start()
thr_out.start()
thr_err.start()
r = p.wait()
thr_out.join()
thr_err.join()
m.acquire()
l.write("{0} -- exited: {1}\n".format(p.pid, r))
l.close()
sys.exit(r)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment