我在我的大学机器上运行了一个 python 程序,我意识到它需要的时间比我预期的要多。代码的一个循环打印一些输出。我想将此输出保存在一个文件中,并在后台发送当前正在运行的程序,因为我需要从系统中注销。
这(如何将已经运行的进程置于 nohup 下?)解释了如何将其发送到后台。有没有什么方法可以保存每秒显示在屏幕上的输出,例如通过使用tee
我在我的大学机器上运行了一个 python 程序,我意识到它需要的时间比我预期的要多。代码的一个循环打印一些输出。我想将此输出保存在一个文件中,并在后台发送当前正在运行的程序,因为我需要从系统中注销。
这(如何将已经运行的进程置于 nohup 下?)解释了如何将其发送到后台。有没有什么方法可以保存每秒显示在屏幕上的输出,例如通过使用tee
我没有尝试过,但这个邪恶的黑客可能会奏效。
查找程序正在使用的文件描述符:
ls -l /proc/<your-pid>/fd
将调试器附加到进程(可执行文件类似于/usr/bin/python
):
gdb --pid=<your-pid> <executable>
O_CREAT
打开您想要的新文件(您可能需要查找和的数值O_WRONLY
):
(gdb) set $newfd = open("myfile", O_CREAT | O_WRONLY)
将您在步骤 1 中找到的旧文件描述符替换为新文件描述符。
(gdb) call dup2(<old-fd>, $newfd)
(gdb) call close($newfd)
设置程序再次运行并断开调试器
(gdb) detach
(gdb) quit
这仅在程序中存在open
和dup2
函数时才有效。
警告:这可能会导致您的程序崩溃!
如果程序已经启动,则需要修改(见下文)来重定向其输出。相反,您可以/应该事先采取预防措施。
我发现始终在屏幕会话中运行远程命令非常有用。这使您可以:
tee
,也可以向上滚动查看程序打印的内容;关于黑客部分:
如果你被卡在运行一个很长很重要的程序,并且无法使用上述方法重新启动它,还是有希望的。
可以通过文件系统找到每个进程的打开文件描述符(包括其当前的标准输出)/proc
。使用它,您可以交换文件描述符并让命令切换到即时输出其他地方。
该脚本 (fdswap.sh)使用 gdb 从正在运行的进程下换出文件描述符,并且有一篇文章解释了如何使用它。
简而言之:找到正在运行的进程的pid,然后运行ls -l /proc/$pid/fd/0
查找其当前输出到哪里,然后使用上面的脚本将其换出:fdswap.sh /dev/pts/$vty /path/to/new/output $pid
.