How to Get a Process's Stdin by a Process Id

How can I get a process's stdin by a process id?

Simply write to /proc/PID/fd/1:

import os.path
pid = os.getpid() # Replace your PID here - writing to your own process is boring
with open(os.path.join('/proc', str(pid), 'fd', '1'), 'a') as stdin:
stdin.write('Hello there\n')

Bash Read Stdin from Given PID

You cannot interact with a program's file descriptors after it has been started. The entries in /proc/$pid/fd/ simply tell you where the file descriptors are connected -- you can write to the place which is connected to stdout, and find out where it's reading its stdin from, but not change what they are connected to or inject new data into any of those streams.

A common workaround for this is to run the program under a tool which enables these operations (expect, tmux, etc) but of course that needs to happen at the time you start the program.

How to write data to existing process's STDIN from external 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

C/C++ - Run system(process &) and then write to its stdin

I used the mplayer slave option and the input as a fifo file. It is working correctly.

Create the Linux fifo file with mkfifo:

system("mkfifo /tmp/slpiplay_fifo");

Open mplayer with:

system("mplayer -slave -idle -really-quiet -input file=/tmp/slpiplay_fifo /mnt/usb_slpiplay/* &");

Pass a "next" command to mplayer by using the fifo:

system("echo \"pt_step 1\" >> /tmp/slpiplay_fifo");

How to get the PID of a process that is piped to another process in Bash?

Write tail's PID to file descriptor 3, and then capture it from there.

( tail -f $1 & echo $! >&3 ) 3>pid | nc -l -p 9977
kill $(<pid)

How can a process find the pids of processes it communicates with over a pipe?

Note that one end of a pipe might be open in more than one process simultaneously (through fork() or sendmsg file-descriptor transmission), so you might not get just one answer.

In Linux, you can examine /proc/<pid>/fd to see what fds it has open (you need to be root, or the same uid as the target process). I just ran grep a | grep b and got the following output:

/proc/10442/fd:
total 0
dr-x------ 2 nneonneo nneonneo 0 Sep 20 02:19 .
dr-xr-xr-x 7 nneonneo nneonneo 0 Sep 20 02:19 ..
lrwx------ 1 nneonneo nneonneo 64 Sep 20 02:19 0 -> /dev/pts/5
l-wx------ 1 nneonneo nneonneo 64 Sep 20 02:19 1 -> pipe:[100815116]
lrwx------ 1 nneonneo nneonneo 64 Sep 20 02:19 2 -> /dev/pts/5

/proc/10443/fd:
total 0
dr-x------ 2 nneonneo nneonneo 0 Sep 20 02:19 .
dr-xr-xr-x 7 nneonneo nneonneo 0 Sep 20 02:19 ..
lr-x------ 1 nneonneo nneonneo 64 Sep 20 02:19 0 -> pipe:[100815116]
lrwx------ 1 nneonneo nneonneo 64 Sep 20 02:19 1 -> /dev/pts/5
lrwx------ 1 nneonneo nneonneo 64 Sep 20 02:19 2 -> /dev/pts/5

So it follows that by using readlink on your own process's fd, followed by readlink on other process fds you own, you can figure out who is on the other side of the pipe.

Madly hackish way to find out (from within a Bash script) which pids and fds are connected to a particular pipe:

get_fd_target() {
pid=$1
fd=$2
readlink /proc/$pid/fd/$fd
}

find_fd_target() {
target=$1
for i in /proc/*/fd/*; do
if [ "`readlink $i`" == "$target" ]; then
echo $i
fi
done
}

Then, if you want to find out what fds on the system are connected to your script's stdin:

find_fd_target `get_fd_target $$ 0`

How do I find the process ID (pid) of a process started in java?

This guy calls out to bash to get the PID. I'm not sure if there is an java solution to the problem.

/**
* Gets a string representing the pid of this program - Java VM
*/
public static String getPid() throws IOException,InterruptedException {

Vector<String> commands=new Vector<String>();
commands.add("/bin/bash");
commands.add("-c");
commands.add("echo $PPID");
ProcessBuilder pb=new ProcessBuilder(commands);

Process pr=pb.start();
pr.waitFor();
if (pr.exitValue()==0) {
BufferedReader outReader=new BufferedReader(new InputStreamReader(pr.getInputStream()));
return outReader.readLine().trim();
} else {
System.out.println("Error while getting PID");
return "";
}
}

Source:
http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-java-program



Related Topics



Leave a reply



Submit