是否可以以编程方式捕获 Linux 上已经运行的进程的标准输出(和标准输入)?(也许将其重定向到管道?)
如果该解决方案在用户空间中工作(意味着不需要 root 权限),那将是最好的。
我已经看到显然使用 gdb 的答案,但我想在没有 gdb 的情况下这样做。
编辑:澄清一下:不,我无权访问代码,我也不想更改二进制文件,我希望解决方案从单独的进程中工作。无论如何,目标进程已经在运行。
是否可以以编程方式捕获 Linux 上已经运行的进程的标准输出(和标准输入)?(也许将其重定向到管道?)
如果该解决方案在用户空间中工作(意味着不需要 root 权限),那将是最好的。
我已经看到显然使用 gdb 的答案,但我想在没有 gdb 的情况下这样做。
编辑:澄清一下:不,我无权访问代码,我也不想更改二进制文件,我希望解决方案从单独的进程中工作。无论如何,目标进程已经在运行。
从进程本身内部(假设您可以在 C 中更改其代码),您可以尝试freopen(3),也许是
FILE*newout = freopen("/some/path", "w", stdout);
if (!newout) { perror("freopen"); exit (EXIT_FAILURE); }
stdout = newout;
另请参见stdio(3)。dup2
(否则STDOUT_FILENO
)。
在流程之外,您可能会使用/proc/$PID/fd/
dup2 (2)或重定向或tee(1),/proc/$PID/fd/0
用于您的流程的标准输入$PID
, 用于您的流程/proc/$PID/fd/1
的标准输出等。有关更多信息,$PID
请参见proc(5) .
如果您已经开始该过程,您可以使用gdb
实际重定向stdout
或strace
截取对write
et.al的调用。
如果您不想使用gdb
,或者strace
您可能需要基本上做与这些相同的事情。他们正在做的魔术是使用该ptrace
功能来跟踪其他过程。这将要求您有权跟踪程序(这也gdb
需要strace
),作为普通用户,您无法跟踪其他用户的程序。
Linux Journal 有一篇关于使用 ptrace的文章,展示了你是如何做到的。需要注意的一点是,这将取决于平台:您必须专门为您使用的平台编写代码,文章似乎有(32 位)x86 平台的示例。