如何redirect已经运行的进程的输出

通常我会开始一个类似的命令

longcommand &; 

我知道你可以通过做类似的东西来redirect它

 longcommand > /dev/null; 

例如摆脱输出或

 longcommand 2>&1 > output.log 

捕捉输出。

但是我有时会忘记,并且想知道事实之后是否有办法捕获或redirect。

 longcommand ctrl-z bg 2>&1 > /dev/null 

或类似的东西,所以我可以继续使用terminal,而无需在terminal上popup消息。

请参阅从运行过程redirect输出

首先,我在一个会话中运行cat > foo1命令,并testingstdin中的数据是否被复制到文件中。 然后在另一个会话中redirect输出。

首先find进程的PID:

 $ ps aux | grep cat rjc 6760 0.0 0.0 1580 376 pts/5 S+ 15:31 0:00 cat 

现在检查它打开的文件句柄:

 $ 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 6.4.90-debian [license stuff snipped] Attaching to program: /bin/cat, process 6760 [snip other stuff that's not interesting now] (gdb) p close(1) $1 = 0 (gdb) p creat("/tmp/foo3", 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 

在GDB中的p命令将打印一个expression式的值,一个expression式可以是一个函数来调用,它可以是一个系统调用…所以我执行一个close()系统调用并传递文件句柄1,然后我执行一个creat()系统调用来打开一个新文件。 creat()的结果是1,这意味着它取代了以前的文件句柄。 如果我想为stdout和stderr使用相同的文件,或者如果我想用其他编号replace文件句柄,则需要调用dup2()系统调用来实现该结果。

对于这个例子,我select使用creat()而不是open()因为参数较less。 标志的Cmacros在GDB中是不可用的(它不使用C头文件),所以我必须读头文件才能发现它 – 这并不难,但是需要更多的时间。 请注意,0600是拥有读取/写入权限的所有者的八进制权限,而组和其他人则无权访问。 它也可以使用0作为该参数,然后在文件上运行chmod。

之后,我validation结果:

 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/foo3 <==== lrwx—— 1 rjc rjc 64 2008-02-27 15:32 2 -> /dev/pts/5 

catinput更多的数据会导致文件/tmp/foo3被追加到。

如果要closures原始会话,则需要closures所有文件句柄,打开一个新的设备,该设备可以是控制的tty,然后调用setsid()

Dupx

Dupx是一个简单的* nix工具,用于redirect已经运行的进程的标准输出/input/错误。

动机

我经常发现自己处于一个通过SSH启动远程系统的过程比我预期的要久的情况。 我需要打破SSH连接,但是如果我这样做,如果它尝试写入一个破损的pipe道的标准输出/错误的过程将会死亡。 我希望我可以暂停^ Z的过程,然后做一个

 bg %1 >/tmp/stdout 2>/tmp/stderr 

不幸的是,这不会工作(在我知道的贝壳)。

http://www.isi.edu/~yuri/dupx/

你也可以使用reredirect( https://github.com/jerome-pouiller/reredirect/ )来完成。

types

 reredirect -m FILE PID 

和输出(标准和错误)将被写入文件。

reredirect README还解释了如何恢复进程的原始状态,如何redirect到另一个命令或只redirectstdout或stderr。

(reredirect似乎有比在另一个答案中描述的Dupx相同的function,但它不依赖于Gdb)。

屏幕

如果进程在屏幕会话中运行,则可以使用屏幕的日志命令将该窗口的输出logging到文件中:

切换到脚本的窗口, Ca Hlogin。
现在你可以 :

 $ tail -f screenlog.2 | grep whatever 

从屏幕的手册页:

日志[开|关]

开始/停止将当前窗口的输出写入窗口默认目录中的文件“screenlog.n”,其中n是当前窗口的编号。 这个文件名可以用'logfile'命令改变。 如果没有给出参数,则logging的状态被切换。 如果会话日志已经存在,则会将其附加到文件的前一个内容。 会话日志中不包含当前内容和回滚历史logging的内容。 默认是“closures”。

我确定tmux也有类似的东西。

我在互联网上收集了一些信息,并准备了无需外部工具的脚本: 请参阅我的回复 。 希望这是有帮助的。