我有一个在我的大学机器上运行的python程序,我意识到它将花费比我预期更多的时间。代码的一个循环打印一些输出。我想将此输出保存在文件中,并在后台发送当前正在运行的程序,因为我需要从系统注销。
这个(How do I put an already-running process under nohup?)解释了如何将其发送到后台。有没有什么方法可以保存每秒在屏幕上显示的输出,例如使用tee
答案 0 :(得分:2)
我没有尝试过,但是这个邪恶的黑客可能会工作。
查找程序正在使用的文件描述符:
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
函数时才会有效。
警告:这可能会导致程序崩溃!
答案 1 :(得分:1)
如果该程序已经启动,则需要进行黑客攻击(见下文)以重定向其输出。相反,您可以/应该事先采取预防措施。
我发现始终在screen会话中运行远程命令非常有用。这允许您:
tee
,也可以向上滚动并查看程序打印的内容; 关于黑客攻击部分:
如果您遇到一个非常长而重要的程序,并且无法重新启动它以使用上述方法,那么仍有希望。
可以通过/proc
文件系统找到每个进程的打开文件描述符(包括其当前的stdout)。使用它,您可以交换文件描述符并让命令切换到动态输出其他地方。
This script (fdswap.sh)使用gdb从正在运行的进程中交换文件描述符,there's an article解释如何使用它。
简而言之:找到正在运行的进程的pid,然后运行ls -l /proc/$pid/fd/0
以查找其当前输出的位置,然后使用上面的脚本将其交换出来:fdswap.sh /dev/pts/$vty /path/to/new/output $pid
。