Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 285
mooz Avatar asked Mar 21 '11 05:03

mooz


People also ask

Can a process write to its own Stdin?

You can't "push to own stdin", but you can redirect a file to your own stdin.

How do I send Stdin to a running process?

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.


1 Answers

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

like image 79
Rumple Stiltskin Avatar answered Sep 22 '22 12:09

Rumple Stiltskin