管道破裂(Broken pipe)错误输出泛滥的问题排查与解决方案咨询
管道破裂(Broken pipe)错误输出泛滥的问题排查与解决方案咨询
最近几个月我的系统里一直被一个问题困扰——到处都是Broken pipe(管道破裂)的错误输出,实在烦不胜烦。先给大家看看具体的错误场景:
# 问题示例:man命令触发bzip2报错 $ man man #err# bzip2: I/O or other error, bailing out. Possible reason follows. #err# bzip2: Broken pipe #err# Input file = (stdin), output file = (stdout) #err# #err# bzip2: I/O or other error, bailing out. Possible reason follows. #err# bzip2: Broken pipe #err# Input file = (stdin), output file = (stdout) # 这个问题通过替换bzip2解决了:把/bin/bzip2从指向bzip2-reference改成lbzip2 # 第二个场景:find管道到head报错 find -type f -name '*.pdf' | head -1 #err# find: ‘standard output’: Broken pipe #err# find: write error # 这个用awk替代head解决了:find -type f -name '*.pdf' | awk 'NR==1' # 还有这些暂时没搞定的: tar tvf archive.tar | head #err# tar: stdout: write error sed $'s/\t/\t-\t/' table.tsv | head | column -ts $'\t' -R 1; #err# sed: couldn't write 42 items to stdout: Broken pipe
我的系统是Gentoo,已安装的相关包信息:
app-shells/bash-5.1_p16-r6: /usr/bin/bash app-arch/tar-1.35: /usr/bin/gtar sys-apps/findutils-4.9.0-r2: /usr/bin/gfind sys-apps/sed-4.9: /usr/bin/gsed sys-libs/glibc-2.38-r10: sys-apps/coreutils-9.4: sys-apps/systemd-255.3-r1:
额外的系统信息:
grep ^Sig /proc/self/status #out# SigQ: 3/256943 #out# SigPnd:0000000000000000 #out# SigBlk:0000000000000000 #out# SigIgn:0000000000001000 #out# SigCgt:0000000000000400 # 登录方式:通过虚拟终端vt1登录,然后启动startx进入图形界面
我一直记得Unix哲学里有一条“避免不必要的输出”,毕竟我90%的操作都是在终端里,这些错误 spam真的太影响体验了。我自己想了几种解决思路,但都不太满意:
- 替换工具实现:比如把bzip2-reference换成lbzip2,这个确实解决了man的问题,但不能覆盖所有场景
- 替换用法:用
awk 'NR<11'替代head——不过我有点纠结,管道被中断明明是合理操作啊?如果输入是几个GiB、TiB甚至无限流(比如curl或者串口输入),总不能让程序一直读下去吧? - 给每个管道命令加
2>/dev/null:这明显是饮鸩止渴,会把真正有用的错误信息也屏蔽掉 - 降级软件包:现在做不到了,而且我也想保持系统更新
- 在
/etc/portage/patches/里加补丁:理论上可行,但感觉太折腾了,完全是下策
更糟的是,现在感觉整个管道使用的惯例都被破坏了——man man用不了,head也出问题,正常的管道操作到处报错。我总觉得自己是不是错过了什么最近的变化?难道是某个GNU工具或者系统组件的更新导致了这种错误输出泛滥?有没有人知道这背后的原因?
另外,有没有更简单的全局解决方案?比如修改/etc/下的某个配置文件就能关掉这个错误输出?或者有环境变量可以在/etc/profile里设置?甚至是编译时的参数?肯定有更合理的办法吧?
备注:内容来源于stack exchange,提问作者Hincor




