头脑风暴-记一道有趣的问题

2018年8月7日玩 22:43:45在帅老师的群里,“N31-行者灬无疆”问:

问题

第一种  grep 'a*' <`ls` ,第二种grep ajie  <ols 是这样子么?

我的见解

刚开始我就注意到了这道问题,我对于“N31-行者灬无疆”的说法是否定的,由于电脑在实验室,所以没有实际操作。我根据输出字体的颜色判断(显然对grep做了别名,alias grep='grep --color=auto')第一,二种grep 是做了执行的。但自己又说不出能说服自己的见解,我开始的见解是第一种:ls | grep a*没有执行而是直接执行的grep a*,原因是根据输出的字体颜色得出的结论。第二种:ls | grep 'a*'是执行先执行ls,在将ls的输出通过管道交给grep去匹配。但这中见解显然也是存在矛盾的,因为第一种: ls | grep a* 及匹配到了文件名又匹配到了内容。

帅老师第一次模拟:

 

没有输出内容!

群内见解

群内有人认为:应该输出a.txt。持这种观点的群友有不少。

还有群友认为:pattern部分需要使用引号引用起来。不然bash不会将a*用正则表达式解释,用ls | grep "a*"试试应该是对的。不加引号的话,bash优先解释啊,会将a*解释为以字母a开头的任意字符串,就轮不到grep去处理了。或者说,即使grep处理了,也不是grep所理解的正则表达式了,而是bash的通配符。我不同意这个说法,因为系统不会欺骗,字体颜色明明显示grep是做了处理的。

之后群里还出现了别的说法,但基本第一种解释不同。

帅老师解答

终于在帅老师的探索下找到了正确答案:

两个问题,1个是管道问题,一个是grep的a*被shell解释了

ls | grep a*,管道两边的进程同时启动,ls的输出放进管道,但是grep a*的a*被shell扩展为a开头的文件,你的root目录下有多个a开头的文件,所以你管道里的内容不会被grep读取,因为它已经有输入了
[root@node3 root]# grep a*
ab.txt:aaaa
ab.txt:aaaaaaa
ac.txt:bba
a.log:aaaabbb
a.txt:aaaa
a.txt:aaaaaaa

你的a文件被当作了grep的pattern
被匹配的文件是除了a的其它a开头文件
这是grep的参数
第一个'a'被grep当作了pattern
如果你把a文件删除,你会一个都匹配不出来

这个ab.txt被当作pattern
但是后面的ac.txt a.log。。。。文件中不包含字符串'ab.txt',所以匹配不到,然后你的ls | grep 'a*',因为这个时候grep缺少输入,所以会从管道读数据

,当作输入文件,管道右边的程序不一定会读取管道左边的内容。只有当管道右边的程序缺少stdin的时候,才会从滚到读数据。这里的ls是多余的,因为grep不需要从ls读取数据作为stdin。在bash中,通配符只是在文件名扩展的时候用的,它会扩展为文件名,然后作为命令的参数。因为你这里的grep除了a*外没有任何参数,所以文件名扩展后排在第一个位的文件"a"就被当作grep的pattern参数部分,其余的被当作grep的输入文件

N31-行者灬无疆:我一开始也是抓取不到内容,然后我发现对方目录下有个 a 文件


这个是ls ab.txt | strace grep a*的结果
这个是ls | strace grep a*的结果,这里并没有读取ls的"ab.txt\n",而是直接打开文件,读取里面的内容的
所以,当进程已经有了stdin的时候,不会读取管道的数据作为stdin
不过可能加上"-"会强制当作stdin

 

总结:

  a*因为没有引号保护,在执行前被Bash按照通配符规则解释成了 a aa aaa ......,并依次与当前目录下的文件进行匹配,匹配到的结果依次排列在grep后面并以空格分隔,于是命令被展开成grep a a.txt a.log ...... 随后进行了执行。第一个a被识别为pattern,而后面的字符串则被识别为文件名。

     这么描述应该好理解点吧。而加-强行读入的内容则是被识别为了文本而非文件名(ls命令输出的是文本)。   关键是管道的机制让人蒙圈。

这件事对我的影响:


帅老师的解答问题的思路,让我学到了许多:
1.遇到问题,不要根据自己的想法去猜测,特别是不懂的问题
2.问题本身不可怕,特别是在Linux中,专业的人士是根据实际测得的数据得出的结论
3.在没有实践前最好不要发表言论,ui时候思考不如实践

对了,还没隆重的介绍我们的帅老师呢:先说好他是个秃子,毕竟头不秃不能说自己在学IT。
他就是:博客园--骏马金龙 

骏马金龙:http://www.cnblogs.com/f-ck-need-u/

 

 

猜你喜欢

转载自blog.csdn.net/zisefeizhu/article/details/81509865