Reputation: 4875
Is it possible to programmatically capture stdout (and stdin) of an already running process on Linux? (Maybe redirect it to a pipe?)
It would be best if the solution worked in userspace (meaning without needing root privileges).
I've seen an answer apparently using gdb, but I'd like to do it without gdb.
EDIT: To clarify: no, I don't have access to the code, neither do I want to change the binary, I want the solution to work from a separate process. The target process is already running anyway.
Upvotes: 3
Views: 3396
Reputation: 14390
If you've already started the process you can use gdb
to actually redirect stdout
or strace
to just intercept the calls to write
et.al.
If you don't want to use gdb
or strace
you would probably need to basically do the same thing as these do. The magic they're doing is to use the ptrace
function to trace the other process. This will require that you have the right to trace the program (which also gdb
and strace
requires), as a normal user you can't trace programs of other users.
Linux Journal has an article about playing with ptrace that shows how you do it. One thing to note is that this will be platform dependent: you have to write the code specifically for the platform you're using, the article seems to have examples for the (32 bit) x86 platform.
Upvotes: 1
Reputation: 1
From inside the process itself (assuming you can change its code in C) you might try freopen(3), perhaps as
FILE*newout = freopen("/some/path", "w", stdout);
if (!newout) { perror("freopen"); exit (EXIT_FAILURE); }
stdout = newout;
See also stdio(3). (Otherwise dup2
the STDOUT_FILENO
).
From outside of the process you might perhaps play with /proc/$PID/fd/
that is dup2(2), or redirecting, or tee(1), the /proc/$PID/fd/0
for the stdin of your process $PID
, the /proc/$PID/fd/1
for the stdout of your process $PID
etc. See proc(5) for more.
Upvotes: 5