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?
You can't "push to own stdin", but you can redirect a file to your own stdin.
It is possible to send input text to a running process without running the screen utility, or any other fancy utility. And it can be done by sending this input text to the process' standard input "file" /proc/PID#/fd/0 . However, the input text needs to be sent in a special way to be read by the process.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With