转载请注明地址: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啊
本人出于个人兴趣,创建了一个个人公众号,每天筛选国外网友发现的有趣的事情推送到公众号,欢迎关注!