Bash下如何捕获非stdout/stderr的线程转储输出?
捕获直接写入终端的输出
你遇到的这种情况,大概率是那些线程转储内容没有通过stdout或stderr输出,而是直接写入了终端设备文件(/dev/tty)——很多程序在处理异常、输出调试信息时会这么做,尤其是库级别的输出,会绕过标准流直接和终端交互。
给你几个靠谱的解决方法:
方法1:用script命令(最推荐)
script是专门用来记录终端会话全量输出的工具,它会创建一个伪终端让程序运行,不管程序是往标准流还是直接写终端的内容,都会被完整捕获。用法很简单:
script -c "make test" full_output.log
执行后,所有输出(包括你之前抓不到的线程转储)都会被保存到full_output.log文件里,直接查看这个文件就行。
方法2:用strace定位输出目标(进阶排查)
如果你想确认这些输出到底是往哪个文件描述符写的,可以用strace追踪程序的系统调用:
strace -e write make test 2>&1 | grep -E 'write\([0-9]+,.*'
这个命令会过滤出所有write系统调用,你能看到程序往哪个fd(比如write(2, ...)对应stderr,write(3, ...)可能是打开的/dev/tty)写入内容。如果确认是往/dev/tty写的,也可以通过临时重定向终端设备的方式捕获,但script已经足够简单,一般不用这么麻烦。
方法3:针对GTest/OpenCV场景的输出调整
既然你知道是opencv_ts和GTest的冲突导致的,也可以尝试从程序层面控制输出:
- 在初始化GTest前,添加
::testing::GTEST_FLAG(output) = "stdout";,强制GTest把所有测试相关输出打到标准输出; - 或者通过环境变量
OPENCV_LOG_LEVEL=ERROR压低OpenCV的输出级别,减少冲突带来的异常输出。
内容的提问来源于stack exchange,提问作者kutschkem
相关产品推荐
相关产品推荐

