|
@@ -1,77 +0,0 @@
|
|
|
-
|
|
|
-
|
|
|
-"""
|
|
|
-> sstream = io.StringIO()
|
|
|
-> subprocess.run(['hostname'], stdout=sstream, check=True)
|
|
|
-io.UnsupportedOperation: fileno
|
|
|
-"""
|
|
|
-
|
|
|
-import os
|
|
|
-import select
|
|
|
-import threading
|
|
|
-
|
|
|
-
|
|
|
-def rselect(fd, timeout_seconds=None):
|
|
|
- """ Wait until file descriptor is ready for reading.
|
|
|
- Return True if ready. Return False if timeout was reached.
|
|
|
-
|
|
|
- select.select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)
|
|
|
- """
|
|
|
- rlist, wlist, xlist = select.select([fd], [], [], timeout_seconds)
|
|
|
- return fd in rlist
|
|
|
-
|
|
|
-
|
|
|
-class SubprocessTee:
|
|
|
-
|
|
|
-
|
|
|
- BUFFER_SIZE_BYTES = 8196
|
|
|
- READ_TIMEOUT_SECONDS = 0.01
|
|
|
-
|
|
|
- def __init__(self, sinks):
|
|
|
- self._sinks = sinks
|
|
|
-
|
|
|
- def __enter__(self):
|
|
|
- self._read_fd, self._write_fd = os.pipe()
|
|
|
- self._thread = threading.Thread(target=self._loop)
|
|
|
- self._thread.start()
|
|
|
- return self
|
|
|
-
|
|
|
- def _write(self, data):
|
|
|
- for sink in self._sinks:
|
|
|
- if isinstance(sink, io.TextIOWrapper):
|
|
|
- sink.buffer.write(data)
|
|
|
- else:
|
|
|
- sink.write(data)
|
|
|
-
|
|
|
- def _loop(self):
|
|
|
- while True:
|
|
|
- try:
|
|
|
- if rselect(self._read_fd, self.READ_TIMEOUT_SECONDS):
|
|
|
- self._write(os.read(self._read_fd, self.BUFFER_SIZE_BYTES))
|
|
|
- except OSError:
|
|
|
- return
|
|
|
-
|
|
|
- def fileno(self):
|
|
|
- return self._write_fd
|
|
|
-
|
|
|
- def __exit__(self, exc_type, exc_value, traceback):
|
|
|
- os.close(self._read_fd)
|
|
|
- os.close(self._write_fd)
|
|
|
-
|
|
|
- self._thread.join()
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-import io
|
|
|
-import subprocess
|
|
|
-import sys
|
|
|
-
|
|
|
-with open('hostname', 'bw') as file_out:
|
|
|
- bstream = io.BytesIO()
|
|
|
- with SubprocessTee([sys.stdout, sys.stderr, file_out, bstream]) as tee:
|
|
|
- subprocess.run(['hostname'], stdout=tee, check=True)
|
|
|
-
|
|
|
-print('hostname bstream: {!r}'.format(bstream.getvalue()))
|
|
|
-with open('hostname', 'r') as file_in:
|
|
|
- print('hostname file: {!r}'.format(file_in.read()))
|