![gnome-terminal 以“grep:写入错误:管道损坏”消息启动](https://linux22.com/image/1054451/gnome-terminal%20%E4%BB%A5%E2%80%9Cgrep%EF%BC%9A%E5%86%99%E5%85%A5%E9%94%99%E8%AF%AF%EF%BC%9A%E7%AE%A1%E9%81%93%E6%8D%9F%E5%9D%8F%E2%80%9D%E6%B6%88%E6%81%AF%E5%90%AF%E5%8A%A8.png)
我正在运行 Ubuntu 14.04.3,它是最新的。我不知道为什么,几天来我grep: write error: Broken pipe
在启动时开始收到消息gnome 终端。这似乎无害,但它困扰着我。我该如何调试它?
编辑:我将别名和函数分别移至单独的文件(例如.bash_aliases
和).bash_functions
,并添加了一个命令来从中加载它们.bashrc
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
if [ -f ~/.bash_functions ]; then
. ~/.bash_functions
fi
如果我不加载,.bash_functions
问题就会消失。
我正在尝试通过逐一禁用每个功能来找出有问题的功能。
这个给了我同样的错误,但是当我禁用它时,我仍然收到同样的错误,所以我可能有更多的错误功能。
ls -lt $PWD| grep ^d | head -1 | cut -b 51-
grep: development
write error: Broken pipe
我不知道为什么我会开始犯这个错误。
编辑2:
我在这里发现了类似的问题博肯管
问题的根源似乎也类似。
我尝试了链接中给出的测试命令,但出现了同样的错误:
bash -c '(while echo foo; do :; done); echo status=$? >&2' | head
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
bash: line 0: echo: write error: Broken pipe
status=0
编辑3:
虽然unbuffer
我下面发布的解决方法作为我自己问题的答案有效,但我对它并不满意,但我对调试的了解有限。根据此链接https://lists.gnu.org/archive/html/bug-coreutils/2007-11/msg00080.html它源于另一个任务的 SIGPIPE 陷阱,并且此链接 https://lists.gnu.org/archive/html/bug-coreutils/2007-11/msg00154.html 查明问题的确切原因,这是我最近遇到麻烦的 pam 身份验证模块之一。
答案1
超级用户的回答对这个问题有很好的解释:我该如何修复“管道破裂”错误?。
管道中的命令是异步运行的:这意味着在管道中command1 | command2
无法保证command1
会在之前结束command2
。
当使用时[...] | grep | head -n 1
,head
只要读取一行就会结束;如果在grep
完成写入管道之前发生这种情况,grep
则会收到 SIGPIPE 信号并输出错误。
正如超级用户在下面的答案中所解释的那样,一种解决方法是将head
管道中之前的输出通过管道传输到tail -n +1
first,这将忽略 SIGPIPE 信号:
command | tail -n +1 | head -n 1
但在这种情况下甚至不需要head
,因为grep
有一个选项可以仅打印第一个匹配项:
[...] | grep -m 1
答案2
经过几个小时的努力,我找到了一个可行的解决方法(我希望如此)
问题似乎更加深刻和复杂。很多人都遇到了同样的错误。修复它超出了我的能力范围。
最接近的解决方法发布在这里我怎样才能修复破裂的管道错误由 Andrew Beals 在下面发布:
ls -lt $PWD|dd obs=1M | grep -m 1 ^d | cut -b 51-
不整洁。
当我直觉它与管道缓冲区相关时,我尝试了如下unbuffer
命令:
unbuffer ls -lt $PWD| grep -m 1 ^d | cut -b 51-
效果很好。
我希望有人发布问题的真正原因。
编辑:bash 大师会建议这个简单的解决方案,将 stderr 重定向到/dev/null
ls -lt $PWD 2>/dev/null | grep -m 1 ^d | cut -b 51-