ADB Shell执行tail -f命令无法持续显示日志如何解决
问题修复方案
按优先级从高到低排查解决:
- 优先排查C程序自身的输出缓冲问题
嵌入式环境下C程序对文件输出默认是全缓冲模式,缓冲区攒够4KB/8KB数据才会实际写入磁盘,tail自然读不到实时日志,选任意一种方案处理即可:- 改代码逻辑:每次打印日志后主动刷新缓冲区,用
std::cout << log_str << std::endl(endl自带强制刷缓冲),或者程序入口处直接关闭全缓冲:setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); - 不想重新编译二进制的话,用
stdbuf启动程序强制关闭输出缓冲:stdbuf -o0 -e0 ./your_binary_path > main.log 2>&1
- 改代码逻辑:每次打印日志后主动刷新缓冲区,用
- 其次排查adb管道和tail命令的缓冲问题
adb跨设备传输默认带管道缓冲,就算目标机上tail读到了新日志,也可能攒一批才传回主机:- 优先替换命令为
adb shell tail -F main.log,大写F参数除了支持日志文件被截断/轮转后自动重连,多数嵌入式tail实现里该参数默认启用行输出模式,不会攒缓冲 - 上述命令无效的话,强制关闭管道缓冲:
adb shell 'tail -f main.log | stdbuf -o0 cat'
- 优先替换命令为
- 最后排查Yocto镜像自带tail的兼容性问题
Yocto最小镜像默认用busybox提供的精简版tail,-f参数的实时跟踪逻辑存在已知bug,直接在构建配置conf/local.conf中添加配置加入全功能版tail:
重新构建烧录镜像后,coreutils提供的全功能tail就不会出现实时跟踪失效的问题。IMAGE_INSTALL:append = " coreutils"
快速排查技巧:直接进入adb交互shell(执行
adb shell不跟后续命令),在目标机本地执行tail -f main.log,如果本地也看不到实时日志,就是程序缓冲问题;如果本地日志实时输出,主机端看不到,就是adb管道缓冲问题。
内容的提问来源于stack exchange,提问作者Pulkit Sharma
相关产品推荐
相关产品推荐

