diff --git a/boottools/utils.py b/boottools/utils.py index b1385f2..f382bfa 100644 --- a/boottools/utils.py +++ b/boottools/utils.py @@ -3,23 +3,53 @@ import subprocess import re import os import configparser +import selectors logger = logging.getLogger ('boottools') def run (args): - cp = subprocess.run (args, text=True, capture_output=True) - if cp.returncode: - logger.error ('command "{}" failed with rc "{}"'.format (' '.join(args), cp.returncode)) + stdout = stderr = '' + logger.debug ('run 10 args "{}"'.format (' '.join(args))) + sel = selectors.DefaultSelector() + p = subprocess.Popen (args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + sel.register (p.stdout.fileno(), selectors.EVENT_READ) + sel.register (p.stderr.fileno(), selectors.EVENT_READ) + while True: + events = sel.select() + #logger.debug (f'got {len(events)} events') + for key, _ in events: + if key.fileobj == p.stdout.fileno(): + #logger.debug (f'reading from stdout') + line = p.stdout.readline() + if not line: break + stdout += line + logger.debug (line.rstrip()) + elif key.fileobj == p.stderr.fileno(): + #logger.debug (f'reading from stderr') + line = p.stderr.readline() + if not line: break + stderr += line + logger.warn (line.rstrip()) + if p.poll() != None: + #logger.debug ('process exited, breaking loop') + break + sel.close() + #p.stdout.close() + #p.stderr.close() - logger.error ('stdout follows:') - for i in cp.stdout.strip().split('\n'): logger.error (' ' + i) + logger.debug (f'p.returncode {p.returncode}') + if p.returncode: + logger.error ('command "{}" failed with rc "{}"'.format (' '.join(args), p.returncode)) + + #logger.error ('stdout follows:') + #for i in cp.stdout.strip().split('\n'): logger.error (' ' + i) logger.error ('stderr follows:') for i in cp.stderr.strip().split('\n'): logger.error (' ' + i) - raise Exception ('command "{}" failed with rc "{}"'.format (' '.join(args), cp.returncode)) - stdout = cp.stdout.strip() - stderr = cp.stderr.strip() + raise Exception ('command "{}" failed with rc "{}"'.format (' '.join(args), p.returncode)) + stdout = stdout.strip() + stderr = stderr.strip() return stdout, stderr def grep (regex, file):