Spaces:
Sleeping
Sleeping
import os | |
import subprocess | |
import sys | |
import threading | |
class ProcessMonitor: | |
def __init__(self): | |
self.process = None | |
self.stdout = "" | |
self.stderr = "" | |
self.lock = threading.Lock() | |
def start_process(self, command): | |
self.process = subprocess.Popen( | |
command, | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE, | |
bufsize=1, | |
universal_newlines=True, | |
) | |
# Set pipes to non-blocking mode | |
fd_out = self.process.stdout.fileno() | |
fd_err = self.process.stderr.fileno() | |
if sys.platform != "win32": | |
import fcntl | |
fl_out = fcntl.fcntl(fd_out, fcntl.F_GETFL) | |
fl_err = fcntl.fcntl(fd_err, fcntl.F_GETFL) | |
fcntl.fcntl(fd_out, fcntl.F_SETFL, fl_out | os.O_NONBLOCK) | |
fcntl.fcntl(fd_err, fcntl.F_SETFL, fl_err | os.O_NONBLOCK) | |
# Start threads to read stdout and stderr | |
threading.Thread(target=self._read_stdout).start() | |
threading.Thread(target=self._read_stderr).start() | |
def _read_stdout(self): | |
while self.process is not None and self.process.poll() is None: | |
try: | |
output = self.process.stdout.read() | |
if output: | |
with self.lock: | |
self.stdout += output | |
except: | |
pass | |
def _read_stderr(self): | |
while self.process is not None and self.process.poll() is None: | |
try: | |
error = self.process.stderr.read() | |
if error: | |
with self.lock: | |
self.stderr += error | |
except: | |
pass | |
def get_output(self): | |
with self.lock: | |
return self.stdout, self.stderr | |
def stop_process(self): | |
if self.process: | |
self.process.terminate() | |
self.process = None | |
if __name__ == "__main__": | |
import time | |
pm = ProcessMonitor() | |
pm.start_process( | |
[ | |
"python", | |
"-u", | |
"-c", | |
"import time; [print(i) or time.sleep(1) for i in range(5)]", | |
] | |
) | |
while pm.process and pm.process.poll() is None: | |
stdout, stderr = pm.get_output() | |
if stdout: | |
print("STDOUT:", stdout) | |
if stderr: | |
print("STDERR:", stderr) | |
time.sleep(1) | |
stdout, stderr = pm.get_output() | |
print("Final STDOUT:", stdout) | |
print("Final STDERR:", stderr) | |