![如何将 stdout 和 stderr 保存到文件同时仍然可以看到输出?](https://linux22.com/image/1413531/%E5%A6%82%E4%BD%95%E5%B0%86%20stdout%20%E5%92%8C%20stderr%20%E4%BF%9D%E5%AD%98%E5%88%B0%E6%96%87%E4%BB%B6%E5%90%8C%E6%97%B6%E4%BB%8D%E7%84%B6%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0%E8%BE%93%E5%87%BA%EF%BC%9F.png)
我正在尝试调试一个生成大量数据的程序。但是我想要调试的事件在一段随机时间后发生(我无法强制执行)。因此,我需要在 shell 中查看 stdout 和 stderr,并将相同的输出保存到文件中以供进一步分析,并在 shell 输出中看到所需内容时立即中断。
我找到了script
这个命令询问 Ubuntu 主题但我无法让它工作,脚本说:
$ script "./client -p 4242 -n test"
Script started, output file is ./client -p 4242 -n test
然后退出。该文件包含:
Script started on Thu Jun 26 13:51:12 2014
Script done on Thu Jun 26 13:51:12 2014
所以script
不起作用。该./client
文件是一个python脚本。我也尝试用启动它,$ python client -p 4242 -n test
但它也不起作用。
我也在同一线程上看到一些带有tee
管道的答案,但我无法将其输出到我的 shell 并查看发生了什么:
$ ./client -p 4242 -n test | tee output.log
给我一个等待的光标,但什么也没有发生。所以tee
不起作用。
还有其他解决方案吗?或者我注定要等待一段时间并中断程序并希望它经历我正在寻找的事件?
非常感谢您的帮助!
PS 我使用的是 zshell (带有 oh-my-zsh)、Mac OSX 10.9.3、Python 2.7.5
编辑:我可能不得不提一下,我正在使用该multiprocessing
模块,并且该./client
脚本启动了多个其他Process
es。可能是因为这个原因吗?我仍然不明白为什么它无法捕获./client
进程输出...
编辑2:我尝试了下面 Matteo 的答案(非常感谢您的帮助)但它变得越来越奇怪:
如果该过程失败(服务器关闭),我可以看到输出:
$ ./client -p 4242 -n test 2>&1 | tee output.log
Process Process-1:
Client # 1: Could not connect to server. Stopping.
Spawner: New client # 1 started...
Done.
$
但如果它看起来正在运行,我什么也看不到:
$ ./client -p 4242 -n test 2>&1 | tee output.log
^C [voluntary interrupt after a lot of waiting]
$ cat output.log
$
在上面的日志中(失败的地方),你可以看到新进程打印前Spawner
尽管主程序 ( ) 是在主程序之后启动的,但它仍然运行。因此,这看起来像是一些非常奇怪的输出魔法。
答案1
答案2
胜利!
正如问题中提到的,我使用 pythonmultiprocessing.Process
从主客户端生成新进程。因此,输出被缓冲,并等待缓冲区已满后再刷新,但似乎命令从未发生过这种情况| tee
。因此永远不会打印任何内容并无休止地等待。
因此,sys.stdout.flush()
解决方案是在每个print
语句后添加一个如上所述这里:
print "Player # " + int(self.id) + " joined the map"
sys.stdout.flush() #<==== THIS MAKES IT ALL WORK !
此后,Matteo 的答案非常有效,并且可以同时在 shell 和文本文件中进行输出。
$ ./client -p 4242 -n test 2>&1 | tee output.log`
$ cat output.log
Player # 1 joined the map.
Player # 1 updated it's inventory.
[...]