如何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
在
cat
input更多的数据会导致文件/tmp/foo3
被追加到。如果要closures原始会话,则需要closures所有文件句柄,打开一个新的设备,该设备可以是控制的tty,然后调用
setsid()
。
Dupx
Dupx是一个简单的* nix工具,用于redirect已经运行的进程的标准输出/input/错误。
动机
我经常发现自己处于一个通过SSH启动远程系统的过程比我预期的要久的情况。 我需要打破SSH连接,但是如果我这样做,如果它尝试写入一个破损的pipe道的标准输出/错误的过程将会死亡。 我希望我可以暂停^ Z的过程,然后做一个
bg %1 >/tmp/stdout 2>/tmp/stderr
不幸的是,这不会工作(在我知道的贝壳)。
你也可以使用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也有类似的东西。
我在互联网上收集了一些信息,并准备了无需外部工具的脚本: 请参阅我的回复 。 希望这是有帮助的。