|
@@ -14,7 +14,7 @@ def run_with_log(args, *, check = True, input = None, **kwargs): |
|
|
`check` has the same semantics as on `subprocess.run`, i.e. raises an exception if the process exits non-zero. |
|
|
`check` has the same semantics as on `subprocess.run`, i.e. raises an exception if the process exits non-zero. |
|
|
`input`, if specified, is a `bytes` object that is fed to the subprocess via stdin. |
|
|
`input`, if specified, is a `bytes` object that is fed to the subprocess via stdin. |
|
|
`stdin`, `stdout`, and `stderr` kwargs must not be used. |
|
|
`stdin`, `stdout`, and `stderr` kwargs must not be used. |
|
|
Returns a tuple with the process's exit status and its stdout output. |
|
|
|
|
|
|
|
|
Returns a tuple with the process's exit status, its stdout output, and its stderr output. |
|
|
''' |
|
|
''' |
|
|
badKwargs = {'stdin', 'stdout', 'stderr'}.intersection(set(kwargs)) |
|
|
badKwargs = {'stdin', 'stdout', 'stderr'}.intersection(set(kwargs)) |
|
|
if badKwargs: |
|
|
if badKwargs: |
|
@@ -29,6 +29,7 @@ def run_with_log(args, *, check = True, input = None, **kwargs): |
|
|
sel.register(p.stdout, selectors.EVENT_READ) |
|
|
sel.register(p.stdout, selectors.EVENT_READ) |
|
|
sel.register(p.stderr, selectors.EVENT_READ) |
|
|
sel.register(p.stderr, selectors.EVENT_READ) |
|
|
stdout = [] |
|
|
stdout = [] |
|
|
|
|
|
stderr = [] |
|
|
stderrBuf = b'' |
|
|
stderrBuf = b'' |
|
|
if input is not None: |
|
|
if input is not None: |
|
|
stdinView = memoryview(input) |
|
|
stdinView = memoryview(input) |
|
@@ -53,6 +54,7 @@ def run_with_log(args, *, check = True, input = None, **kwargs): |
|
|
key.fileobj.close() |
|
|
key.fileobj.close() |
|
|
continue |
|
|
continue |
|
|
if key.fileobj is p.stderr: |
|
|
if key.fileobj is p.stderr: |
|
|
|
|
|
stderr.append(data) |
|
|
stderrBuf += data |
|
|
stderrBuf += data |
|
|
*lines, stderrBuf = stderrBuf.replace(b'\r', b'\n').rsplit(b'\n', 1) |
|
|
*lines, stderrBuf = stderrBuf.replace(b'\r', b'\n').rsplit(b'\n', 1) |
|
|
if not lines: |
|
|
if not lines: |
|
@@ -70,4 +72,4 @@ def run_with_log(args, *, check = True, input = None, **kwargs): |
|
|
_logger.info(f'Process exited with status {p.returncode}') |
|
|
_logger.info(f'Process exited with status {p.returncode}') |
|
|
if check and p.returncode != 0: |
|
|
if check and p.returncode != 0: |
|
|
raise subprocess.CalledProcessError(returncode = p.returncode, cmd = args) |
|
|
raise subprocess.CalledProcessError(returncode = p.returncode, cmd = args) |
|
|
return (p.returncode, b''.join(stdout).decode('utf-8')) |
|
|
|
|
|
|
|
|
return (p.returncode, b''.join(stdout).decode('utf-8'), b''.join(stderr).decode('utf-8')) |