如何重定向已经运行的进程的 stdout/stderr?

non*_*all 7 ubuntu process redirect stdout

(在 Ubuntu 10.04 64 位服务器上运行)

昨天,我犯了一个错误,即在没有使用 screen 的情况下通过 SSH 启动一个进程(我没有意识到这需要几天的时间才能运行)。我今天花了一整天的时间试图找出某种方法,我可以从 SSH 的铁腕中撬出进程的输出,以便我可以重新启动我的客户端机器,但没有任何进展。

我尝试使用 gdb 并按照本页底部的说明进行操作,但是当我运行第一个 gdb 命令来创建文件时,我收到一条错误消息,指出No symbol table is loaded. Use the "file" command. 根据我收集的内容,这意味着我必须重新编译其输出的程序我正在尝试重定向,这当然对我来说绝对没有帮助,因为它已经在运行。

我还认为我可以使用 retty 将输出重定向到另一个终端,但显然它不能在 64 位平台上编译。

如何将此进程的输出重定向到另一个终端或文件?

Der*_*rfK 5

看起来给出的那些说明gdb在几个方面是不正确和不完整的。

首先,您需要使用

gdb [executablefile] [pid]
Run Code Online (Sandbox Code Playgroud)

以便 GDB 知道它实际连接的程序是什么。我刚刚对此进行了测试,它可以使用剥离的可执行文件。请注意,当 gdb 附加到进程时,进程将被挂起。如果此进程通过网络进行通信,请快速键入,否则网络连接可能会超时。

其次,根据命令不解释什么,他们正在做的,和指令,你应该cd“命令,你希望你的程序文件写入到一个目录”是错误的,因为GDB是问原来的程序来执行的creat()功能. 给出的示例将在正在运行的程序的当前工作目录中创建 myprog.stderr 和 myprog.stdout 文件,而不是在您运行 gdb 的目录中。如果您不知道该程序的 CWD 是什么(或查看ls -l /proc/[pid]/cwd),请在此处使用绝对路径名。

第三,在没有解释的情况下运行,重要的是要知道第一个参数dup2()是前一个返回的文件描述符编号,creat()所以如果这个正在运行的程序打开了几个文件,你可能会以这样的交换结束

(gdb) call creat("/home/me/myprog.stdout",0600)
$1 = 7
(gdb) call dup2(7,1)
$2 = 1
(gdb) call creat("/home/me/myprog.stderr",0600)
$3 = 8
(gdb) call dup2(8,2)
$4 = 2
Run Code Online (Sandbox Code Playgroud)

当您退出 gdb 时,它会询问您是否要“无论如何退出(并分离它)”,答案是肯定的。

最后,bg并且disown是bash的内建命令。如果您没有使用 bash,那么从这里开始您就靠自己了。 bg将暂停的作业移动到后台,就好像它是使用 启动的一样somecommand &,并disown在 bash 退出时将程序从 bash 的活动程序列表中删除到 SIGHUP。