Как записать данные в STDIN существующего процесса из внешнего процесса?

StackOverflow https://stackoverflow.com/questions/5374255

Вопрос

Я ищу способы записать данные в существующий процесс STDIN от внешних процессов и нашел аналогичный вопрос Как транслировать данные в Stdin программы из разных локальных/удаленных процессов в Python? в Stackoverlow.

В этой теме @michael говорит, что мы можем получить файловые дескрипторы существующего процесса в пути, как ниже, и позволили записать данные в них на Linux.

/proc/$PID/fd/

Итак, я создал простой сценарий, перечисленный ниже, чтобы проверить данные о написании на сценарии STDIN (а также TTY) от внешнего процесса.

#!/usr/bin/env python

import os, sys

def get_ttyname():
    for f in sys.stdin, sys.stdout, sys.stderr:
        if f.isatty():
            return os.ttyname(f.fileno())
    return None

if __name__ == "__main__":
    print("Try commands below")

    print("$ echo 'foobar' > {0}".format(get_ttyname()))
    print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid()))

    print("read :: [" + sys.stdin.readline() + "]")

Этот тестовый скрипт показывает пути STDIN а также TTY А потом подождите, пока один написать, это STDIN.

Я запустил этот сценарий и получил сообщения ниже.

Try commands below
$ echo 'foobar' > /dev/pts/6
$ echo 'foobar' > /proc/3308/fd/0

Итак, я выполнил команду echo 'foobar' > /dev/pts/6 а также echo 'foobar' > /proc/3308/fd/0 из другого терминала. После выполнения обеих команд сообщение foobar дважды отображается на терминале. Тестовый скрипт работает, но это все. Линия print("read :: [" + sys.stdin.readline() + "]") не был выполнен.

Есть ли способы записать данные из внешних процессов в существующий процесс STDIN (или другие дескрипторы файлов), т.е. вызвать выполнение строкиprint("read :: [" + sys.stdin.readline() + "]") от других процессов?

Это было полезно?

Решение

Ваш код не будет работать.
/proc/pid/fd/0 это ссылка на /dev/pts/6 файл.

$ echo 'foobar'>/dev/pts/6
$ echo 'foobar'>/proc/pid/fd/0

Так как обе команды записывают на терминал. Этот вход идет в терминал, а не в процесс.

Это будет работать, если Stdin интенсивно является трубой.
Например, test.py является :

#!/usr/bin/python

import os, sys
if __name__ == "__main__":
    print("Try commands below")
    print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid()))
    while True:
        print("read :: [" + sys.stdin.readline() + "]")
        pass

Запустите это как:

$ (while [ 1 ]; do sleep 1; done) | python test.py

Теперь из другого терминала напишите что -нибудь /proc/pid/fd/0 И это придет test.py

Другие советы

Я хочу оставить здесь пример, который я нашел полезным. Это небольшая модификация верного трюка выше, которая с периодически провалилась на моей машине.

# pipe cat to your long running process
( cat ) | ./your_server &
server_pid=$!
# send an echo to your cat process that will close cat and in my hypothetical case the server too
echo "quit\n" > "/proc/$server_pid/fd/0"

Это было полезно для меня, потому что по конкретным причинам я не мог использовать mkfifo, который идеально подходит для этого сценария.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top