attach to process by pid?

D

Danny Shevitz

Howdy,

Is there any way to attach to an already running process by pid? I want to send
commands from python to an application that is already running. I don't want to
give the command name to subprocess.Popen.

thanks,
Danny
 
N

Nobody

I think he wants to attach to another process's stdin/stdout and
read/write from/to them.
I don't know if this is possible but it would be a great addition for psutil.

It's not even a meaningful concept, let alone possible.
 
A

Alexander Kapps

It's not even a meaningful concept, let alone possible.

Unless I misunderstand something, it is possible (at least on Linux):

Two terminal windows:

1:
alex@frittenbude:~$ grep foobar

2:
alex@frittenbude:~$ ps ax|grep 'grep foobar'
13075 pts/4 S+ 0:00 grep --color=auto grep foobar
alex@frittenbude:~$ echo foobar > /proc/13075/fd/0

That this is *highly* system dependent, problematic in many regards
and just terrible hackery is another issue.
 
J

James Mills

On 10.03.2011 23:25, Nobody wrote:
Unless I misunderstand something, it is possible (at least on Linux):

Two terminal windows:

1:
alex@frittenbude:~$ grep foobar

2:
alex@frittenbude:~$ ps ax|grep 'grep foobar'
13075 pts/4    S+     0:00 grep --color=auto grep foobar
alex@frittenbude:~$ echo foobar > /proc/13075/fd/0

This works fine on the Linux platform (perhaps other UNIX-like
platforms have similar concepts). You're simply writing to
the processes's stdin (file descriptor of 0)

Probably not a portable solution.

cheers
James
 
G

Grant Edwards

Unless I misunderstand something, it is possible (at least on Linux):

Sometimes. [See below.]
Two terminal windows:

1:
alex@frittenbude:~$ grep foobar

2:
alex@frittenbude:~$ ps ax|grep 'grep foobar'
13075 pts/4 S+ 0:00 grep --color=auto grep foobar
alex@frittenbude:~$ echo foobar > /proc/13075/fd/0

That this is *highly* system dependent, problematic in many regards
and just terrible hackery is another issue.

That doesn't work for me:

Terminal 1:

$ grep foobar
asdf

Terminal 1:
$ ps axf | grep "grep foobar"
7203 pts/4 S+ 0:00 \_ grep foobar
7205 pts/5 S+ 0:00 \_ grep grep foobar

$ echo "asdf" >/proc/7203/fd/0

What the echo did was write to the tty device from which the "grep" is
reading. The string "asdf" went directly to the tty. It didn't go to
grep's stdin (grep wouldn't have displayed it).


It _does_ work on processes who's stdin is an anonymous pipe:

terminal window 1:

$ (while sleep 1; do date; done) | grep foobar
foobar
asdffoobarqwer

terminal window 2:

$ ps axf | grep "grep foobar"
7229 pts/4 S+ 0:00 \_ grep foobar
7268 pts/5 S+ 0:00 \_ grep grep foobar
$ echo "asdf" >/proc/7229/fd/0
$ echo "foobar" >/proc/7229/fd/0
$ echo "qwer" >/proc/7229/fd/0
$ echo "asdffoobarqwer" >/proc/7229/fd/0

We know that the data written to /proc/7229/fd/0 was going to grep's
stdin, since lines with foobar were printed and lines without weren't.

I'll do an 'echo "hi there" >/proc/fd/7346/fd/0 where 7346 is the pid
of the instance of the "jed" text editor that I'm using to edit this
post. The "hi there" string showed up in my terminal window, but it
didn't actually get inserted in the file, because "jed" didn't see it.

/proc/fd/7346/fd/0 points to /dev/pts/0. Writing to /dev/pts/0 sends
data to the terminal window, _not_ to process 7346's stdin. Writing
to /proc/fd/7346/fd/1 does the same thing. Writing to
/proc/fd/7346/fd/2 sends the data to the tty where the write was done,
since /proc/fd/7346/fd/2 points to /dev/tty, and /dev/tty points to
different things depending on who's doing the writing.

There are _some_ cases where you can write to /proc/<pid>/fd/0 and the
program specified by <pid> sees the data on it's stdin. But, it doesn't
work in many common cases.
 
N

Nobody

Unless I misunderstand something,

You do ...
it is possible (at least on Linux):

Two terminal windows:

1:
alex@frittenbude:~$ grep foobar

2:
alex@frittenbude:~$ ps ax|grep 'grep foobar'
13075 pts/4 S+ 0:00 grep --color=auto grep foobar
alex@frittenbude:~$ echo foobar > /proc/13075/fd/0

The /proc/<pid>/fd/<n> pseudo-files are just aliases for whatever "object"
(file, device, socket, ...) is attached to that descriptor. Writing to the
pseudo-file writes to the file, not to the descriptor. E.g.:

$ > foo.txt
$ sleep 100 < foo.txt &
[1] 17380
$ cat foo.txt
$ echo hello > /proc/17380/fd/0
$ cat foo.txt
hello

Similarly, if the process' standard input is a terminal, writing to
/proc/<pid>/fd/0 will write to the terminal. It will not cause the data to
appear on the process' standard input.

There are a few situations where it will work (for some values of "work").

E.g. in the case where standard input is a file, writing to .../fd/0 will
write to the file. If you open .../fd/0 in append mode (or if the process
hasn't started reading it yet), the next time the process reads from the
file, it will read the data which was just written. Of course, this
assumes that you have write permission on the file and don't mind
modifying it (and, if you *don't* use append mode, overwriting it).

Also, if .../fd/0 is a pipe (named or otherwise), opening it for write
will get you the write end of the pipe, while the process' standard input
has the read end. This is the one case which will usually work as expected.

Essentially, you can read or write files (pipes, devices, etc). You can't
read or write to another process' descriptors.

In the case of a pipe, writing to the pipe itself Does The Right Thing. In
some other cases, you could write to some other object to get the desired
result; e.g. if the process' stdin is a pseudo-terminal, writing to the
corresponding master device would cause the data to appear on the process'
stdin (but I don't know if that's actually possible with Unix98-style
ptys).

In other cases, there's no way to achieve the desired result. E.g. if the
process' stdin is a physical terminal, the only way to cause the
device to generate data is by pressing keys on the terminal.
 
A

Alexander Kapps

You do ...

Many thanks for the correction and lesson (to Grand Edwards too)!

I still try to digest your explanations. I thought, that processes
just do something like dup()'ing the file descriptors of their
terminal but after some strace experiments, I think that is totally
wrong.

I'd like to learn more about this (how processes, their controlling
terminals and the std file descriptors relate)

Do you know any links to deeper material (tried Google but what I've
found is to shallow)
 
N

Nobody

I still try to digest your explanations. I thought, that processes
just do something like dup()'ing the file descriptors of their
terminal but after some strace experiments, I think that is totally
wrong.

Actually, the way that descriptors are inherited by a fork()ed process is
akin to dup(). In particular, any descriptors which refer to a
random-access stream (anything which supports lseek(), i.e. a file or
block device) share a single file position, so lseek()ing on a descriptor
will affect the file position for any copies of that stream created by
dup(), dup2() or fork(); the only way to get a stream with its own
position is to open() the file (etc) again. Likewise for the file
status flags (O_APPEND, O_NONBLOCK, etc). However, a "cloned" descriptor
gets its own copy of the file descriptor flags (i.e. the FD_CLOEXEC flag).

open()ing the /proc/<pid>/fd/<n> pseudo-files is a bit of a hack, and
Linux-specific. The behaviour is a cross between the fork/dup behaviour
and a separate open() operation. Opening a descriptor which refers to a
pipe opens the "correct" end based upon the mode (read or write), as with
a normal open(), but the resulting descriptor shares its file position and
status flags, as with fork/dup.
I'd like to learn more about this (how processes, their controlling
terminals and the std file descriptors relate)

There's nothing special about the standard descriptors. A child process
inherits all of its parent's descriptors. If the parent has closed any of
its standard descriptors, they'll still be closed in the child
(one exception: Linux will force these descriptors to be open when
executing a setuid executable to avoid potential security issues).

Also, the controlling terminal is unrelated to the standard descriptors.
Upon login, a terminal will typically be assigned as both the controlling
terminal and all three standard descriptors, but they may diverge after
that. E.g. if you start a pipeline ("foo | bar | baz") from the shell,
some of the standard descriptors will be replaced by pipes, but the
controlling terminal will be unaffected. The controlling terminal relates
primarily to signals (Ctrl-C, Ctrl-Z, etc) and job control.
Do you know any links to deeper material (tried Google but what I've
found is to shallow)

I don't have any links. If you want to understand the core Unix API, the
best reference I know of is Stevens ("Advanced Programming in the Unix
Environment", by W. Richard Stevens). Unfortunately, it's not cheap.

In spite of the title, it doesn't assume any prior Unix knowledge; the
"Advanced" mainly refers to the fact that it's the opposite of the "Learn
X in Five Minutes" books, i.e. it's thorough. That's how it comes to >700
pages while only covering the core API (files, processes, and terminals;
no sockets, no X, no I18N, ...).
 
A

Alexander Kapps

I don't have any links. If you want to understand the core Unix API, the
best reference I know of is Stevens ("Advanced Programming in the Unix
Environment", by W. Richard Stevens). Unfortunately, it's not cheap.

In spite of the title, it doesn't assume any prior Unix knowledge; the
"Advanced" mainly refers to the fact that it's the opposite of the "Learn
X in Five Minutes" books, i.e. it's thorough. That's how it comes to>700
pages while only covering the core API (files, processes, and terminals;
no sockets, no X, no I18N, ...).

Thanks, Nobody and Dan. I'll have a look at the book.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,805
Latest member
ClydeHeld1

Latest Threads

Top