如何在仍然看到输出的同时将stdout和stderr保存到文件中?


0

我正在尝试调试生成大量数据的程序。但是我想要调试的事件发生在一段随机的时间之后(我不能强迫它)。因此,我需要在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 file是一个python脚本。我也尝试用它启动它 $ python client -p 4242 -n test 但它也没有用。

我也在同一个帖子上看到了一些答案 tee 和管道,但我不能让它输出到我的shell,看看发生了什么:

$ ./client -p 4242 -n test | tee output.log

给了我一个等待光标,没有任何事情发生。 所以 tee 不起作用

有没有其他解决方案,或者我注定要等待并在一段时间后中断程序,并希望它经历了我正在寻找的事件?

非常感谢你的帮助!

附:我在使用zshell(使用oh-my-zsh),Mac OSX 10.9.3,Python 2.7.5

编辑: 我可能不得不提到我正在使用 multiprocessing 模块和 ./client 脚本启动多个其他 Process ES。可能是因为这个原因吗?我仍然不明白为什么它不会抓住 ./client 过程输出...

EDIT2: 我尝试了下面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 )即使它在它之后开始。所以它看起来像一些非常奇怪的输出魔法。


如果 teescript 没有捕获程序的输出,那么程序可能正在做一些比仅写入stdout / stderr更“聪明”的事情。它可能正在写入/ dev / tty,或者当stdout / stderr不是TTY时它可能会改变它的行为。
Kenster

我正在使用的唯一功能是 print 来自Python的声明(2.7.5)。
achedeuzot

Answers:


2

您可以将标准错误重定向到标准输出,然后使用 tee 复制标准输出并将其存储到文件中。

$ ./client -p 4242 -n test 2>&1  | tee output.log

编辑 :你可以尝试一下命令

$ ( echo "stdout" ; echo "stderr" 1>&2 ) 2>&1  | tee output.log

他们俩 echo s在stdout和stderr上产生输出。你应该看到两者,并且相同 output.log

编辑

您也可以尝试,而不是修改您的程序(刷新) script -q 或者如上所述的其他几种工具 关闭管道中的缓冲


我尝试过这个,因为它在ask Ubuntu线程中被建议但是当我尝试它时shell上没有输出。并且output.log文件为空!我不明白为什么:/它是python 2.7“打印”声明吗?
achedeuzot

1
@matteo的答案是你做出要求的正常方式。当stdout / stderr不是TTY时,这个“客户端”程序可能表现不同。
Kenster

顺便说一句,我在OS X 10.9.3上使用zsh进行了测试,它的行为如上所述。
Matteo

非常感谢你的帮助。不幸的是,它变得越来越奇怪(见第二次编辑)。我会等一些,以防有人知道这可能来自哪里(python?multiprocess?)。
achedeuzot

你的答案是“一般情况”中的正确答案。但由于一些特殊性(Python多处理模块),对我来说不起作用。
achedeuzot

1

胜利!

正如问题所述,我使用的是python multiprocessing.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.
[...]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.