У меня есть следующий код, который работает точно так же, как предполагалось:Как воспроизвести `stdin = sys.stdin` с` stdin = PIPE`?
from subprocess import Popen
process = Popen(
["/bin/bash"],
stdin=sys.stdin,
stdout=sys.stdout,
stderr=sys.stderr,
)
process.wait()
я могу интерактивно использовать Баш, вкладка работы и т.д.
Однако я хочу, чтобы контролировать то, что я посылаю стандартного ввода, так что я d:
import os
import sys
from subprocess import Popen, PIPE
from select import select
process = Popen(
["/bin/bash"],
stdin=PIPE,
stdout=sys.stdout,
stderr=sys.stderr,
)
while True:
if process.poll() is not None:
break
r, _, _ = select([sys.stdin], [], [])
if sys.stdin in r:
stdin = os.read(sys.stdin.fileno(), 1024)
# Do w/e I want with stdin
os.write(process.stdin.fileno(), stdin)
process.wait()
Но поведение просто не то же самое. Я попробовал другой подход (идя через PTY):
import os
import sys
import tty
from subprocess import Popen
from select import select
master, slave = os.openpty()
stdin = sys.stdin.fileno()
try:
tty.setraw(master)
ttyname = os.ttyname(slave)
def _preexec():
os.setsid()
open(ttyname, "r+")
process = Popen(
args=["/bin/bash"],
preexec_fn=_preexec,
stdin=slave,
stdout=sys.stdout,
stderr=sys.stderr,
close_fds=True,
)
while True:
if process.poll() is not None:
break
r, _, _ = select([sys.stdin], [], [])
if sys.stdin in r:
os.write(master, os.read(stdin, 1024))
finally:
os.close(master)
os.close(slave)
И поведение довольно близко, за исключением вкладки по-прежнему не работает. Ну, вкладка правильно отправлена, но мой терминал не показывает завершение, даже если это было сделано bash. Стрелки также показывают ^[[A
вместо того, чтобы проходить историю.
Любая идея?
вы знаете, что (обычно) вы могли бы заменить первый пример кода с: 'subprocess.call ([ '/ бен/Баш'])'? Также вы можете использовать напрямую (или посмотреть, как оно реализовано) 'pty.spawn (['/ bin/bash'], master_read, stdin_read)' (Вам нужно передать '-i',' -l' и т. Д.) ? – jfs