You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

管道破裂(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

火山引擎 最新活动