查看运行进程的stdin / stdout / stderr – Linux内核

有没有办法以一种简单的方式redirect/查看给定运行进程的标准input/标准输出/标准错误(通过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 

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

谢谢

首先,如果你可以改变你的架构,你可以在屏幕,tmux,nohup或dtach之类的东西下运行它,这会让你的生活更轻松。

但是如果你有一个正在运行的程序,你可以使用strace来监视它的内核调用,包括所有的读/写操作。 您将需要限制它看到的(尝试-e ),也许只筛选前3个FD的输出。 还要加上-s因为默认是限制记录的数据的大小。 例如: strace -p <PID> -e read,write -s 1000000

你可以通过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。