我正在寻找从外部进程向现有进程STDIN
写入数据的方法,并在stackoverlow中找到类似的问题How do you stream data into the STDIN of a program from different local/remote processes in Python?。
在那个帖子中,@ 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() + "]")
?
答案 0 :(得分:18)
您的代码无效
/proc/pid/fd/0
是指向/dev/pts/6
文件的链接。
$ echo'foobar'>的/ dev / PTS / 6
$ echo'foobar'> / proc /进程/ 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
答案 1 :(得分:4)
我想留下一个我觉得有用的例子。它是对上面真正的技巧的一个小修改,在我的机器上间歇性地失败。
# 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
,这对于这种情况非常适合。