28

我正在寻找将数据从外部进程写入现有进程的STDIN方法,并发现了类似的问题 How do you stream data into the STDIN from different local/remote processes in 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() + "]")从其他进程调用该行的执行?

4

2 回答 2

23

您的代码将不起作用。
/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

于 2011-03-21T16:43:01.773 回答
6

我想在这里留下一个我觉得有用的例子。这是对上面的 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"

这对我很有帮助,因为由于特殊原因我无法使用mkfifo,这非常适合这种情况。

于 2015-09-18T03:24:07.673 回答