Interaction between Python script and linux shell Interaction between Python script and linux shell shell shell

Interaction between Python script and linux shell


Popen might not be very suitable for interactive programs due to buffering issues and due to the fact that some programs write/read directly from a terminal e.g., to retrieve a password. See Q: Why not just use a pipe (popen())?.

If you want to emulate script utility then you could use pty.spawn(), see the code example in Duplicating terminal output from a Python subprocess or in log syntax errors and uncaught exceptions for a python subprocess and print them to the terminal:

#!/usr/bin/env pythonimport osimport ptyimport syswith 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)

Or you could use pexpect for more flexibility:

import sysimport pexpect # $ pip install pexpectwith open('log', 'ab') as fout:    p = pexpect.spawn("python test.py")    p.logfile = fout # or .logfile_read    p.interact()

If your child process doesn't buffer its output (or it doesn't interfere with the interactivity) and it prints its output to its stdout or stderr then you could try subprocess:

#!/usr/bin/env pythonimport sysfrom subprocess import Popen, PIPE, STDOUTwith 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()

To read both stdout/stderr separately, you could use teed_call() from Python subprocess get children's output to file and terminal?


This should work

import subprocessf = open('file.txt','w')cmd = ['echo','hello','world']subprocess.call(cmd, stdout=f)