Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
470 views
in Technique[技术] by (71.8m points)

linux - How to write data to existing process's STDIN from external process?

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.

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.

/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.

#!/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.

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.

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your code will not work.
/proc/pid/fd/0 is a link to the /dev/pts/6 file.

$ 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 :

#!/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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...