Как записать данные в STDIN существующего процесса из внешнего процесса?
Я ищу способы записи данных в существующий процесс 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() + "]")
из других процессов?
2 ответов
ваш код не будет работать./proc/pid/fd/0
это ссылка .
$ 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
, который идеально подходит для этого сценария.