Python subprocess get children's output to file and terminal? Python subprocess get children's output to file and terminal? python python

Python subprocess get children's output to file and terminal?


The call() function is just Popen(*args, **kwargs).wait(). You could call Popen directly and use stdout=PIPE argument to read from p.stdout:

#!/usr/bin/env pythonimport sysfrom subprocess import Popen, PIPEfrom threading import Threaddef tee(infile, *files):    """Print `infile` to `files` in a separate thread."""    def fanout(infile, *files):        with infile:            for line in iter(infile.readline, b""):                for f in files:                    f.write(line)    t = Thread(target=fanout, args=(infile,) + files)    t.daemon = True    t.start()    return tdef teed_call(cmd_args, **kwargs):    stdout, stderr = [kwargs.pop(s, None) for s in ["stdout", "stderr"]]    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, getattr(sys.stdout, "buffer", sys.stdout))        )    if stderr is not None:        threads.append(            tee(p.stderr, stderr, getattr(sys.stderr, "buffer", sys.stderr))        )    for t in threads:        t.join()  # wait for IO completion    return p.wait()outf, errf = open("out.txt", "wb"), open("err.txt", "wb")assert not teed_call(["cat", __file__], stdout=None, stderr=errf)assert not teed_call(["echo", "abc"], stdout=outf, stderr=errf, bufsize=0)assert teed_call(["gcc", "a b"], close_fds=True, stdout=outf, stderr=errf)


You could use something like this:https://github.com/waszil/subpiper

In your callbacks you can do whatever you like, log, write to file, print, etc. It also supports non-blocking mode.

from subpiper import subpiperdef my_stdout_callback(line: str):    print(f'STDOUT: {line}')def my_stderr_callback(line: str):    print(f'STDERR: {line}')my_additional_path_list = [r'c:\important_location']retcode = subpiper(cmd='echo magic',                   stdout_callback=my_stdout_callback,                   stderr_callback=my_stderr_callback,                   add_path_list=my_additional_path_list)