Tee无法从管道中获得全部输出


12

我有一个脚本,执行以下命令:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH;./some_app -i $INDEX | tee $LOG
echo "Number of errors: $(grep "ERROR" $LOG | wc -l)"

问题可能出在管道上tee。它似乎无法获得全部输出。当应用程序退出时,输出的最后几行(通常是包含致命错误的行)丢失。当我运行不带管道的应用程序时,tee将它们显示在输出中。

如何强制脚本等待tee完成所有输出的处理?


如果将其发送到文件而不是stdout,它可以正常工作吗?
飞行员

Answers:


23

致命错误可能出现在STDERR(2)中,而不是STDOUT(1)中。您可以使用将STDERR重定向到STDOUT,2>&1然后管道也应该捕获它。

./some_app -i $INDEX 2>&1 | tee $LOG

如果您最先遇到缓冲问题,则可以将其强制为无缓冲状态:

stdbuf -o0 ./some_app -i $INDEX 2>&1 | tee $LOG

好,我们越来越近了。现在,我看到致命错误正在打印,但仍然没有完成。有错误的行仅在中间结束,回声输出继续。刷新缓冲区或仅等待该部分完成仍然存在一些问题。
Ladislav Mrnka 2015年

编辑。在我的经验中,很少有什么东西在出口时完全滑过缓冲区,但值得一试。
奥利(Oli)

1
做完了!谢谢。我可能会问太多问题,但是有人知道为什么在传递到其他进程时为什么需要关闭缓冲吗?
Ladislav Mrnka

@Oli一个非常好的人!
飞行员

6

由于错误消息通常显示在STDERR(文件描述符2)上,因此您需要将STDOUT和STDERR都重定向到tee

./some_app -i "$INDEX" |& tee "$LOG"

执行此操作时,./some_app -i $INDEX | tee $LOG您仅会将STDOUT重定向到tee

|& 将导致STDOUT和STDERR都被重定向。

如果您不能仅重定向STDOUT(如以前一样):

./some_app -i "$INDEX" | tee "$LOG"

另一方面,如果您只想重定向STDERR:

./some_app -i "$INDEX" 2>&1 >/dev/null | tee "$LOG"
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.