«Соединить» две трубы вместе?Linux

Ответить Пред. темаСлед. тема
Anonymous
 «Соединить» две трубы вместе?

Сообщение Anonymous »

Я хотел бы запустить процесс, предоставить ему некоторый первоначальный ввод, а затем заставить его «взять на себя» стандартный ввод и вывод, как если бы я его выполнил. Хотя вопрос не зависит от языка, вот поясняющий код Python:

Код: Выделить всё

import os
import sys
import subprocess
pid = os.getpid()

def printer():
print(f"[Printer-{pid}] Startup!")
for line in sys.stdin:
print(f"[Printer-{pid}] {line.strip()}")

def launcher():
try:
print(f"\t[Launcher-{pid}] Sending initial message.")
# launches the "printer()" function in another process.
child = subprocess.Popen(
(sys.executable, __file__, "printer"),
stdin=subprocess.PIPE,
universal_newlines=True,
bufsize=1
)
child.stdin.write("Initial setup message!\n")
print(f"\t[Launcher-{pid}] Turning over control.")
for line in sys.stdin:
child.stdin.write(line)
finally:
child.kill()
child.communicate()

if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == 'printer':
printer()
else:
launcher()
При запуске (без аргументов) получается:

Код: Выделить всё

    [Launcher-24132] Sending initial message.
[Launcher-24132] Turning over control.
[Printer-29572] Startup!
[Printer-29572] Initial setup message!
message from stdin
[Printer-29572] message from stdin
Если бы мне не нужен бит «Сообщение о начальной настройке!\n», я мог бы просто выполнить эквивалент любого языка:

Код: Выделить всё

def launcher_alternate():
subprocess.Popen((sys.executable, __file__, "printer"))
sys.exit(0)
И дочерний процесс унаследует стандартные потоки от своего родителя. (Может быть немного сложнее работать в оболочке, поскольку оболочка будет ожидать своего прямого дочернего элемента, а не внука, но каналы все равно должны быть действительными. Или вместо этого мы могли бы ждать дочернего элемента выхода.)
С сообщением «начальная настройка» возникает ряд проблем:
  • Родительский процесс должен оставаться рядом для пересылки сообщений.
  • Мы удваиваем накладные расходы ядра на передачу данных по каналам.
  • Нам нужно сделать предположения о как мы хотим, чтобы наши потоки буферизовались.
Похоже, что мне нужно что-то вроде «приклеить [входную трубу] изолентой к [выходную трубу] ]". Это похоже на операцию, обратную конвейеру, где вместо создания связанной пары fd мы уничтожаем оба, соединяя их. Существует ли это в Linux/Windows, а если нет, то почему?

Код: Выделить всё

# DOES NOT EXIST (I think.)
os.splice(sys.stdin, child.stdin)
Опять же, я не ищу код Python для пересылки, я ищу ответ на уровне ОС или объяснение (если оно существует), почему его нет. такая особенность. Я упомянул некоторые вещи, специфичные для безымянных каналов Linux, но если именованные каналы или Windows имеют их эквивалент, это тоже будет хорошим ответом.

Подробнее здесь: https://stackoverflow.com/questions/790 ... s-together
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Linux»