The answer associated with the tee is not suitable for your task. Although you can fix the " raw_input() hints" with the -u option to disable buffering:
errf = open('err.txt', 'wb') # any object with .write() method rc = call([sys.executable, '-u', 'test.py'], stderr=errf, bufsize=0, close_fds=True) errf.close()
A more suitable solution might be based on pexpect or pty , example .
running the registration program should look like as soon as the user runs python test.py as usual.
#!/usr/bin/env python import sys import pexpect with open('log', 'ab') as fout: p = pexpect.spawn("python test.py") p.logfile = fout p.interact()
You do not need to install pexpect , it is pure Python, you can put it next to your code.
Here's the tee-based counterpart ( test.py runs silently):
#!/usr/bin/env python import sys from subprocess import Popen, PIPE, STDOUT from threading import Thread def tee(infile, *files): """Print `infile` to `files` in a separate thread.""" def fanout(infile, *files): flushable = [f for f in files if hasattr(f, 'flush')] for c in iter(lambda: infile.read(1), ''): for f in files: f.write(c) for f in flushable: f.flush() infile.close() t = Thread(target=fanout, args=(infile,)+files) t.daemon = True t.start() return t def call(cmd_args, **kwargs): stdout, stderr = [kwargs.pop(s, None) for s in 'stdout', 'stderr'] p = Popen(cmd_args, stdout=None if stdout is None else PIPE, stderr=None if stderr is None else ( STDOUT if stderr is STDOUT else PIPE), **kwargs) threads = [] if stdout is not None: threads.append(tee(p.stdout, stdout, sys.stdout)) if stderr is not None and stderr is not STDOUT: threads.append(tee(p.stderr, stderr, sys.stderr)) for t in threads: t.join()
You need to merge stdout / stderr because of the confusion where raw_input() , getpass.getpass() can print their prompts.
In this case, threads are also not needed:
#!/usr/bin/env python import sys from subprocess import Popen, PIPE, STDOUT with open('log','ab') as file: p = Popen([sys.executable, '-u', 'test.py'], stdout=PIPE, stderr=STDOUT, close_fds=True, bufsize=0) for c in iter(lambda: p.stdout.read(1), ''): for f in [sys.stdout, file]: f.write(c) f.flush() p.stdout.close() rc = p.wait()
Note: the last example and a tee-based solution do not capture the getpass.getpass() pexpect , but pexpect and pty are a solution based on:
#!/usr/bin/env python import os import pty import sys with open('log', 'ab') as file: def read(fd): data = os.read(fd, 1024) file.write(data) file.flush() return data pty.spawn([sys.executable, "test.py"], read)
I don't know if pty.spawn() works on macs.