Что касается статуса файловых потоков, то 1002 * ничего особенного в stdin/stdout/stderr
1 нет. После запуска программы вы можете обращаться с ними как с любым обычным файловым дескриптором. Так что идея повторного связывания stdin
не нужна. Вместо этого, это действительно больше похоже на вопрос о том, как настроить одновременные входные потоки.
Мое первое желание - использовать пару потоков, но я уверен, что это можно сделать с помощью async/await
и возможно, есть и другие способы. В этом случае с потоками должно быть все в порядке, так как оба потока будут в конечном итоге связаны с вводом-выводом и должны освободить GIL (каждый любит, чтобы его раздражали из-за GIL). Это довольно близко (не идеально, но в пределах приблизительного ...):
#!/usr/bin/env python3
import sys
import threading
from time import sleep
user_input = ""
def tty_reader():
global user_input
read_fd = open("/dev/tty", 'r')
while 1:
print("interactive-% ", end="", flush=True)
user_input = read_fd.readline() # block for input
print("\nUser Input: " + str(user_input), end="", flush=True)
def pipe_reader():
while 1:
stdin_text = sys.stdin.readline() # block for input
if stdin_text != user_input:
print("\nPipe Message: " + str(stdin_text), end="", flush=True)
t_tty_reader = threading.Thread(target=tty_reader)
t_pipe_reader = threading.Thread(target=pipe_reader)
t_pipe_reader.start()
sleep(3) # to let the existing 'tail' lines finish printing
t_tty_reader.start()
сохраните его в файл, chmod 755
и запустите так:
tail -f <some file> | ./<python script>
Это запускает 2 темы. Один читает из /dev/tty
, а другой читает из оригинального stdin
, который должен быть присоединен к stdout
команды tail -f
. Оба потока тратят большую часть своего времени на блокировку ввода. Как я уже сказал, это могло бы быть лучше, но это показывает общую идею.
1: Они все еще являются особенными по нескольким причинам: вы получаете их бесплатно; они предварительно установлены в определенной стандартизированной конфигурации; они получают специальную обработку как устройства в /dev
; дочерние процессы наследуют их.