Linux 如何从外部进程将数据写入现有进程的 STDIN?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5374255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write data to existing process's STDIN from external process?
提问by mooz
I'm seeking for ways to write data to the existing process's STDIN
from external processes, and found similar question How do you stream data into the STDIN of a program from different local/remote processes in Python?in stackoverlow.
我正在寻找将数据STDIN
从外部进程写入现有进程的方法,并发现了类似的问题 How do you stream data into the STDIN from different local/remote processes in Python? 在 stackoverlow 中。
In that thread, @Michael says that we can get file descriptors of existing process in path like below, and permitted to write data into them on Linux.
在该线程中,@Michael 说我们可以在如下路径中获取现有进程的文件描述符,并允许在 Linux 上将数据写入其中。
/proc/$PID/fd/
So, I've created a simple script listed below to test writing data to the script's STDIN
(and TTY
) from external process.
因此,我创建了一个下面列出的简单脚本来测试从外部进程向脚本的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() + "]")
This test script shows paths of STDIN
and TTY
and then, wait for one to write it's STDIN
.
这个测试脚本显示了STDIN
和TTY
然后,等待一个人写它的STDIN
.
I launched this script and got messages below.
我启动了这个脚本并在下面收到了消息。
Try commands below
$ echo 'foobar' > /dev/pts/6
$ echo 'foobar' > /proc/3308/fd/0
So, I executed the command echo 'foobar' > /dev/pts/6
and echo 'foobar' > /proc/3308/fd/0
from other terminal. After execution of both commands, message foobar
is displayed twice on the terminal the test script is running on, but that's all. The line print("read :: [" + sys.stdin.readline() + "]")
was not executed.
所以,我执行的命令echo 'foobar' > /dev/pts/6
和echo 'foobar' > /proc/3308/fd/0
从其他终端。执行这两个命令后,foobar
在运行测试脚本的终端上会显示两次消息,仅此而已。该行print("read :: [" + sys.stdin.readline() + "]")
未执行。
Are there any ways to write data from external processes to the existing process's STDIN
(or other file descriptors), i.e. invoke execution of the lineprint("read :: [" + sys.stdin.readline() + "]")
from other processes?
是否有任何方法可以将数据从外部进程写入现有进程STDIN
(或其他文件描述符),即print("read :: [" + sys.stdin.readline() + "]")
从其他进程调用该行的执行?
采纳答案by Rumple Stiltskin
Your code will not work./proc/pid/fd/0
is a link to the /dev/pts/6
file.
您的代码将不起作用。/proc/pid/fd/0
是/dev/pts/6
文件的链接。
$ echo 'foobar' > /dev/pts/6
$ echo 'foobar' > /proc/pid/fd/0
$ echo 'foobar' > /dev/pts/6
$ echo 'foobar' > /proc/pid/fd/0
Since both the commands write to the terminal. This input goes to terminal and not to the process.
由于这两个命令都写入终端。此输入进入终端而不是进程。
It will work if stdin intially is a pipe.
For example, test.py
is :
如果 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
Run this as:
运行它:
$ (while [ 1 ]; do sleep 1; done) | python test.py
Now from another terminal write something to /proc/pid/fd/0
and it will come to test.py
现在从另一个终端写一些东西/proc/pid/fd/0
,它会来test.py
回答by Martín Coll
I want to leave here an example I found useful. It's a slight modification of the while true trick above that failed intermittently on my machine.
我想在这里留下一个我觉得有用的例子。这是对上面的 while true 技巧的轻微修改,该技巧在我的机器上间歇性失败。
# 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"
It was helpful to me because for particular reasons I couldn't use mkfifo
, which is perfect for this scenario.
这对我很有帮助,因为由于特殊原因我无法使用mkfifo
,这非常适合这种情况。