请参阅正在运行的进程的stdin / stdout / stderr - Linux内核

时间:2015-02-03 16:29:12

标签: linux linux-kernel

有没有办法以简单的方式重定向/查看给定运行进程的stdin / stdout / stderr(按PID)?

我尝试了以下内容(假设'pid'包含正在运行的用户进程):

int foo(const void* data, struct file* file, unsigned fd)
{
    printf("Fd = %x\n", fd);
    return 0;
}
struct task_struct* task = pid_task(find_vpid(pid), PIDTYPE_PID);
struct files_struct* fs = task->files;
iterate_fd(fs, 0, foo, NULL);

我得到3次调用foo(这个过程可能有3个打开的文件,这很有意义)但是我无法从它们中读取(从文件指针中读取)。

打印:

0
1
2

是否有可能以一种相当简单的方式实现我的要求?

感谢

2 个答案:

答案 0 :(得分:2)

首先,如果你可以改变你的架构,你可以在screen,tmux,nohup或dtach这样的东西下运行它,这将使你的生活更轻松。

但是如果你有一个正在运行的程序,你可以使用strace监视它的内核调用,包括所有读/写。您需要限制它看到的内容(尝试-e),并且可能只过滤前3个FD的输出。还要添加-s,因为默认设置是限制记录的数据大小。类似于:strace -p <PID> -e read,write -s 1000000

答案 1 :(得分:1)

您可以通过gdb实现它

检查文件句柄process()是否已打开:

$ ls -l /proc/6760/fd
total 3
lrwx—— 1 rjc rjc 64 Feb 27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 Feb 27 15:32 1 -> /tmp/foo1
lrwx—— 1 rjc rjc 64 Feb 27 15:32 2 -> /dev/pts/5

现在运行GDB:

$ gdb -p 6760 /bin/cat
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
[lots more license stuff snipped]
Attaching to program: /bin/cat, process 6760
[snip other stuff that’s not interesting now]

(gdb) p close(1)
$1 = 0

提供新文件名以获取输出 - process_log

(gdb) p creat(“/tmp/process_log″, 0600)
$2 = 1
(gdb) q
The program is running. Quit anyway (and detach it)? (y or n) y
Detaching from program: /bin/cat, process 6760

之后验证结果为:

ls -l /proc/6760/fd/
total 3
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 2008-02-27 15:32 1 -> /tmp/process_log <====
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 2 -> /dev/pts/5

以类似的方式,您也可以重定向stdin,stderr。