У меня есть приведенный ниже скрипт на python, который я использую, чтобы попытаться прочитать программу, в которой нет нужных символов новой строки для всего.Это позволяет выполнять чтение, не беспокоясь о блокировке операций чтения.Однако, поскольку я не знаю достаточно о потоке, я подозреваю, что именно в этом заключается моя проблема.
import subprocess
import shlex
import os
import time
from threading import Thread
import queue
class NonBlockingStreamReader:
def __init__(self, stream):
"""
:param stream: the stream to read from. Usually stdout or stderr.
"""
self._s = stream
self._q = queue.Queue()
def _populate_queue(_stream, _queue):
"""Collect lines from 'stream' and put them in 'queue'"""
while True:
_char = _stream.read(1)
if _char:
_queue.put(_char)
else:
raise UnexpectedEndOfStream
self._t = Thread(
target=_populate_queue,
args=(
self._s,
self._q
)
)
self._t.daemon = True
self._t.start() # Start collecting characters from the stream
def readchar(self, timeout=None):
try:
_tmp = self._q.get(block=timeout is not None, timeout=timeout)
return _tmp
except queue.Empty:
return None
class UnexpectedEndOfStream(Exception):
pass
def main():
proc = subprocess.Popen(
shlex.split('strace -o /home/arts/dlm/trace_output.txt stdbuf -o0 /home/arts/dlm/test'),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
nbsr = NonBlockingStreamReader(proc.stdout)
_data = b''
while True:
_char = nbsr.readchar(0.1)
if not _char:
break
else:
_data += _char
print(_data.decode())
proc.stdin.write(b'12345\n')
_data = b''
while True:
_char = nbsr.readchar(5)
if not _char:
break
else:
_data += _char
print(_data.decode())
print('Annnnd done.')
if __name__ == '__main__':
main()
Вот ожидаемый результат работы программы test
:
Line 1 test
Line 2 test
Line 3 input: 12345 <--- input from user
Line 4 test: 12345
Вотвывод strace:
write(1, "Line 1 test", 11) = 11
write(1, "\n", 1) = 1
write(1, "Line 2 test", 11) = 11
write(1, "\n", 1) = 1
write(1, "Line 3 input: ", 14) = 14
fstat(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb76716d000
read(0, "12345\n", 4096) = 6
write(1, "Line 4 test: 12345\n\n", 20) = 20
exit_group(1) = ?
Это показывает (по крайней мере мне), что приложение предоставляет запрошенный вывод.read(0, "12345\n", 4096)
показывает proc.stdin.write(b'12345\n')
, если я что-то упустил.Следующая строка показывает, что он читает ожидаемый результат.Тем не менее, РЕАЛЬНЫЕ выходные данные:
Line 1 test
Line 2 test
Line 3 input:
Annnnd done.
Если я поставлю некоторые операторы печати после _char = _stream.read(1)
, он ничего не показывает.Если я добавлю их в функцию readchar
, то она покажет None
.
Что-то ломает стандартный вывод, поэтому, куда бы он ни шел, он не идет в трубу.Кто-нибудь может направить меня в правильном направлении?