linux grep通过管道输出到head出现write error: Broken pipe错误



转载请注明地址:http://blog.csdn.net/echoutopia/article/details/51655882


之前做一个分页,利用grep加head加tail实现的:

ls /tmp/conf/usergroup/ | grep -P '^(?!auto-)'| head -n 20 | tail -n 20 | awk -F . '{print $1}'

 grep出来的条数大概有6w条,然后用php的exec去执行这条命令,大概耗时1.3秒,感觉太慢,不能接受。 
  

后面发现直接去终端执行这条命令,real time只有0.27秒,居然差了一秒,于是着手排查问题

开始以为是php派生进程耗时太多,于是exec(“echo aaa"),很快。

后面脑洞大开,会不会是报错了,于是改了下命令:

(ls /tmp/conf/usergroup/ | grep -P '^(?!auto-)'| head -n 20 | tail -n 20 | awk -F . '{print $1}') 2>&1

卧槽,打印php的exec内容,一下在出来了6w多条broken pipe的错误,简直恐怖。

但是这个错误怎么来的呢,去查了下资料,原来是head的原因。

这条命令执行过程中,会派生grep进程和head进程(其他忽略),他们通过管道传输数据,grep往管道写,head从管道读。

因为grep出来的结果又6w多条,所以grep进程会往管道写6w条数据,

但是head在取了20条后,就关闭了管道,但是grep不知道,所以还在一直往没有读端的管道一直写,导致出现了6w多条

write error: Broken pipe错误。。

解决办法:

1、可以把错误重定向到/dev/null,这样就清静了。

2、grep有个-m 参数,即查找到了规定的数目结果后,停止查找。

我改进的命令为:

ls /tmp/conf/usergroup/ | grep -P '^(?!auto-)'-m 20 | tail -n 20 | awk -F . '{print $1}'

一下子速度跟终端也差不多了

只是心里还有个疑问,为啥终端里执行这个命令不会有broken pipe这个错误,希望有人不吝赐教

看来我对linux的了解还只是scratch the surface啊

转载请注明地址:http://blog.csdn.net/echoutopia/article/details/51655882

本人出于个人兴趣,创建了一个个人公众号,每天筛选国外网友发现的有趣的事情推送到公众号,欢迎关注!

linux grep通过管道输出到head出现write error: Broken pipe错误_第1张图片


你可能感兴趣的:(linux,shell,grep,head)