Skip to content

Instantly share code, notes, and snippets.

@Disassembler0
Last active January 20, 2020 22:20
Show Gist options
  • Save Disassembler0/531e2785a7ec1e8545eff5d26c20e050 to your computer and use it in GitHub Desktop.
Save Disassembler0/531e2785a7ec1e8545eff5d26c20e050 to your computer and use it in GitHub Desktop.
import errno
import os
import subprocess
import sys
# Run command and immediately print output as it is generated
def passthru(cmd):
# Create stdout and stderr pseudoterminal pairs
stdout_master, stdout_slave = os.openpty()
stderr_master, stderr_slave = os.openpty()
# Run the command redirecting the output to slave ends of ptys
p = subprocess.Popen(cmd, stdout=stdout_slave, stderr=stderr_slave)
# Close the slave ends on python's end as they have been passed to the process
os.close(stdout_slave)
os.close(stderr_slave)
# Redirect master ends to python's stdout / stderr
readable = {stdout_master: sys.stdout.buffer, stderr_master: sys.stderr.buffer}
while readable:
# Wait for descriptors to be ready
for fd in select.select(readable, [], [])[0]:
try:
# Read the data from the process and write them to python's stdout / stderr
data = os.read(fd, 1024)
readable[fd].write(data)
readable[fd].flush()
except OSError as e:
# Remove the file descriptor on EOF
if e.errno != errno.EIO:
raise
del readable[fd]
# Close the master ends and return the return code of the finished process
os.close(stdout_master)
os.close(stderr_master)
return p.poll()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment