我吃一堑,你长一智 之 使用 .* 匹配文件与目录导致大错


参考资料:
http://stackoverflow.com/questions/2910049/how-to-use-the-wildcard-in-bash-but-exclude-the-parent-directory

事故缘由:
在我的本地home目录下,为了修改所有隐藏文件的属性,使用了.*来匹配执行chown -R,结果导致了整个/home目录以及下面所有其它用户目录的属性都被修改了。最直接的后果就是导致所有其他的用户都无法登陆服务器了,因为我们采用了SSH Key。
而问题的根本原因在于,使用.*在Linux下匹配文件和目录时,.和..会被匹配到。
而即使是这样,那也不会导致问题吧?但事实上并非如此,因为对于/dir1/dir2/dir3/dir4/dir5这样的一个目录结构,.代表的当前目录为dir5,而..则代表上级目录dir4。

正所谓无图无真相,下面是我的相关操作步骤,可以清楚的看到使用.*匹配之后,直接修改了目录dir4与dir5的属性。
chown_hole

因此,正确的做法,应该使用正则表达式 .[^.]* 来精确匹配当前目录下的隐藏文件。
chown_hole_2

最后,我想试一下rm和mv会造成什么样严重的后果,却发现执行rm和mv在匹配.*时会进行保护,并不会造成问题。
chown_hole_3

chown_hole_4

  1. #1 by rainbow on 2014/05/09 - 20:32

    从图中看,还是只匹配到上级目录dir4,上上级应该是dir3吧,楼主再看看,期待回复。

    • #2 by mcsrainbow on 2014/05/10 - 17:29

      当前目录是./,上级目录../是dir5,上上级目录../../当然就是dir4。

      • #3 by rainbow on 2014/05/11 - 03:57

        当前目录是./(就是dir5吧),上级目录../是dir4(第一张图中..是指它只包括dir5,而不是..就是dir5),上上级目录../../当然就是dir3,可以继续交流。

        • #4 by mcsrainbow on 2014/05/11 - 10:19

          你的理解应该是正确的,所以chown应该是匹配了.与..,所以会同时更改dir4和dir5的属性。
          谢谢,相关内容已经更新。

          • #5 by rainbow on 2014/05/11 - 22:51

            嗯,应该是这样的,前后都说得通了。其实我是想转载这篇文章,发现有点“问题”,本着学习linux的态度,才斗胆评论两句,当然还是很高兴能与博主交流。

  2. #6 by sky on 2014/05/10 - 20:31

    你吃一堑,我长一智。

  3. #7 by 销声匿迹 on 2014/05/15 - 14:07

    涨姿势了,,以前一直没注意过,,,

  4. #8 by pgc on 2014/05/21 - 11:27

    我吃一堑,你长一智!说的很好。我也是这样的,这样才慢慢熟练起来

  5. #9 by stxinu on 2014/05/22 - 15:21

    很多都是这样的,没碰到并且没时间去了解的永远不知道,只有碰到了并解决了才知道为什么?该如何处理,才学到了新东西。

  6. #10 by wwenyunkui on 2014/06/17 - 16:38

    写的很好,值得学习。
    顺便说一下rm以及mv命令为啥没有产生严重后果的原因:因为当前的工作目录是dir5,否则一样会产生相当严重单后果,呵呵

  7. #11 by wwenyunkui on 2014/06/17 - 16:39

    顺便问一下博主,ldap单文章啥时候更新?期待已久呀,呵呵

  8. #12 by wwenyunkui on 2014/06/24 - 10:11

    .[^.]* 这个很不错,精确匹配
    另外'执行rm和mv在匹配.*时会进行保护',我觉得是rm、mv命令(进程)正在对dir5目录下的文件进行操作,所以不能不能同时对目录本身进行操作,有点绕口,其实还有很多命令都会如此,比如cp
    [wenyk@wenyk tmp]$ echo test > test/dir1/dir2/dir3/dir4/dir5/.test2.txt
    [wenyk@wenyk tmp]$ echo test > test/dir1/dir2/dir3/dir4/dir5/.test3.txt
    [wenyk@wenyk tmp]$ echo test > test/dir1/dir2/dir3/dir4/dir5/test1.txt
    [wenyk@wenyk tmp]$ cp test/dir1/dir2/dir3/dir4/dir5/.* .
    cp: omitting directory `test/dir1/dir2/dir3/dir4/dir5/.'
    cp: omitting directory `test/dir1/dir2/dir3/dir4/dir5/..'
    我们仍然不能把.*匹配到的dir5一起复制,应该也是这个原因

(will not be published)
*