如何从外部进程将数据写入现有进程的STDIN?
我正在寻求从外部进程向现有进程的STDIN
写入数据的方法,并在stackoverlow中发现了类似的问题How do you stream data into the STDIN of a program from different local/remote processes in Python?。如何从外部进程将数据写入现有进程的STDIN?
在该线程中,@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
文件的链接。
$回声 'foobar的'>的/ dev/PTS/6
$回声 'foobar的'>/proc /进程/ FD/0
由于两个命令写入到终端。该输入进入终端,而不是进程。
这将工作,如果标准输入为inlined是管道。
例如,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
您提出的脚本和命令可以正常工作。所以,一旦我像'$ python test.py'那样从没有管道的终端创建进程,就没有办法执行'print(“read :: [”+ sys.stdin.readline()+“]”)'from外部过程? – mooz 2011-03-21 18:13:40
@mooz:AFAIK没有办法做到这一点。 – 2011-03-24 06:39:54
我想在这里的离开我发现有用的例子。这是对我的机器上间歇性失败的上述真实技巧的轻微修改。
# 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
,这是完美的这种情况下特殊原因。
命名管道(请参见man mkfifo')做你想要的吗? – Andy 2011-03-21 16:05:11
感谢您的建议。我会看看named-pipe。 – mooz 2011-03-21 18:20:47