老哥们,为什么我这行命令就删库了啊!求助 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
CatCode
V2EX    Linux

老哥们,为什么我这行命令就删库了啊!求助

  •  
  •   CatCode 2020-07-15 10:04:44 +08:00 7588 次点击
    这是一个创建于 1915 天前的主题,其中的信息可能已经有所发展或是发生改变。

    命令如下:(危险命令请勿模仿

    # 危险命令请勿模仿 find ./ -type d -print0 -name '.git' | xargs -0 -s1024 /bin/rm -rf 

    危险命令请勿模仿

    原本的想法:这个目录是别的 git 库 clone 过来的,因为所有必要的文件都已经 checkout 出来了。为了在后面遍历文件的步骤中,减少遍历到不必要的文件,于是打算删掉所有名为.git的目录。

    然而,当我运行了这个命令,本目录下所有的子目录都被删除了。我就懵逼了,为啥?

    33 条回复    2020-07-26 21:42:05 +08:00
    larisboy
        1
    larisboy  
       2020-07-15 10:11:31 +08:00
    楼主不先试试 find ./ -type d -print0 -name '.git' 出来的是什么?
    echo1937
        2
    echo1937  
       2020-07-15 10:13:16 +08:00   1
    我试验了一下,
    find ./ -type d -print0 -name '.git' 似乎真正的左右是 find ./ -type d -print0
    find ./ -type d -name '.git' 才是查找.git 的目录

    问题应该在这里.
    3gs
        3
    3gs  
       2020-07-15 10:15:18 +08:00   1
    我猜 -print0 后面的参数会被忽略,应该放后边
        4
    larisboy  
       2020-07-15 10:16:21 +08:00   1
    find path -option [ -print ] [ -exec -ok command ] {} \;


    -print 应该 option 后面
    guanhui07
        5
    guanhui07  
       2020-07-15 10:19:03 +08:00
    还是要谨慎些 打印出来看看啥
    dalidali
        6
    dalidali  
       2020-07-15 10:21:06 +08:00   1
    老哥 艺高人胆大啊
    CatCode
        7
    CatCode  
    OP
       2020-07-15 10:21:21 +08:00
    感谢各位,我重新 clone 了,把-print0 放后面就好了
    我才知道 xargs 的参数是有先后顺序的
    reus
        8
    reus  
       2020-07-15 10:21:56 +08:00
    前几天还有个头条面试官非要说 find 才是正确答案来着?

    find 这种上古东西还是算球了,参数位置影响输出的,垃圾设计。
    sonice
        9
    sonice  
       2020-07-15 10:24:39 +08:00
    @reus 麻烦给个现代一点的命令让我开开眼界
    DJQTDJ
        10
    DJQTDJ  
       2020-07-15 10:27:43 +08:00
    $ find . -name '*.bak' -print0 | xargs -0 rm

    艺高人胆大。
    defunct9
        11
    defunct9  
       2020-07-15 10:27:44 +08:00
    rust 的 fd
    tankren
        12
    tankren  
       2020-07-15 10:33:07 +08:00
    为什么上来就要用组合命令呢 不应该先看看前面返回了啥?
    felixcode
        13
    felixcode  
       2020-07-15 10:47:20 +08:00
    find 我通常用-exec 来做,貌似好控制一些,还可以先不加-exec 查看一下。
    lovecy
        14
    lovecy  
       2020-07-15 10:48:30 +08:00
    这种操作,运行前打印出来检查下先。。
    当然最好还是先统一挪动到备份文件夹,然后一起删除
    securityCoding
        15
    securityCoding  
       2020-07-15 10:50:16 +08:00
    牛批牛批
    xuanbg
        16
    xuanbg  
       2020-07-15 10:50:38 +08:00
    git 本地库删掉没事,再 clone 一次就好了。远程库删掉也没啥,再推送上去就完了。
    reus
        17
    reus  
       2020-07-15 10:54:28 +08:00
    whasyt
        18
    whasyt  
       2020-07-15 11:19:06 +08:00
    find ./ -type d -name '.git' |xargs rm -rf
    huangmingyou
        19
    huangmingyou  
       2020-07-15 11:41:16 +08:00
    find > log.txt ; 这样会安全点。
    ETiV
        20
    ETiV  
       2020-07-15 11:43:37 +08:00 via iPhone
    @CatCode

    是 find 的参数有顺序,不是 xargs
    tlday
        21
    tlday  
       2020-07-15 12:49:00 +08:00
    并不只是 print 位置不对的问题,你如果执行 find ./ -type d -print -name '.git' -exec echo Matched {} \+ 就会有所发现。
    因为上面这条命令等价于 find ./ \( -type d -and -print -and -name '.git' \) -exec echo Matched {} \+

    而在-print 的文档中就说明了,这个“条件”总是为 true,并打印“当前”文件的 pathname 到 stdout 。( This primary always evaluates to true. It prints the pathname of the current file to standard output.)

    不知道为什么楼主会去单用 print 这个选项。因为 print 这个选项还说:假如"-exec, -ls, -print, -print0, -ok"没有任何一个被使用,那么命令会默认最后加一个-print ( If none of -exec, -ls, -print, -print0, or -ok is specified, the given expression shall be effectively replaced by ( given expression ) -print.)

    说 find 是上古东西的当然可以自己写脚本来做嘛,python 一个 os.walk 也不费什么劲。像 find 这种东西一些过时设计已经没法改了,因为肯定有大量的运维脚本依赖于这个“错误”设计。但是对于熟悉的人来说,写这么一段命令肯定比写脚本快得多。
    no1xsyzy
        22
    no1xsyzy  
       2020-07-15 13:18:00 +08:00
    @reus #8 其实是因为 find 是一个不完整的指令式编程语言
    请把 “垃圾设计” 引申到一切指令式编程语言,我会表示完全同意。单指 find,我觉得不行。
    wdidwlia
        23
    wdidwlia  
       2020-07-15 13:25:51 +08:00 via iPhone
    取决于用哪个 shell, 其实 rm 一条命令也能解决
    reus
        24
    reus  
       2020-07-15 14:09:01 +08:00
    @no1xsyzy 一个命令做好自己的事情,要复杂的控制指令,让 shell 来做,就行了。find 又有 exec 又有 delete 等等根本不需要的东西,又各种随意堆砌的参数规则。sed 也有语言,awk 也有语言,但都不像 find 这样残疾,我是不会引申的。糟粕就是糟粕。

    稍微没那么上古的,看看 plan9 怎么做的吧: https://github.com/google/walk
    分开两个命令,一个做遍历一个做过滤,不比 find 好?
    Linco
        25
    Linco  
       2020-07-15 14:46:18 +08:00
    敢把 rm -rf 放到管道后面的都是狠人
    no1xsyzy
        26
    no1xsyzy  
       2020-07-15 15:10:57 +08:00
    @reus #24 还不是因为管道得走一遍内核,而且 sor 反复 fork/exec 无数遍切换(我也想不通为什么要当作 bash 而不是),多花的时间长得可怕。分命令通常是不太可行的。
    残缺倒是真的,前些天碰到什么我甚至记不得是啥情况的边角问题,查了一圈发现只能返回到 shell 再处理。
    大概重新做个语法好点的倒是有用,不过不如自己写脚本了。
    可能 pwsh 有奇效……
    no1xsyzy
        27
    no1xsyzy  
       2020-07-15 15:14:43 +08:00
    @reus #24 残缺归残缺,别把问题丢 “参数位置影响输出” 上…… 至于又想做些复杂功能又做得残缺,git 不也是这样么……
    @tlday #21 看了下,因为是 -print0,采用 '\0' 断而不是 LF 断,后面 xargs 也是 -0,这样可以避免文件名带换行导致错误
    pouta
        28
    pouta  
       2020-07-15 15:17:43 +08:00
    666
    Mutoo
        29
    Mutoo  
       2020-07-15 15:20:39 +08:00
    reus
        30
    reus  
       2020-07-15 15:41:23 +08:00
    @no1xsyzy 问题就是参数位置影响输出,为什么你总是要否定问题所在?

    git 也是这样? git 的命令很明确分成 plumbing 和 porcelain 两类,高层命令做不了的事情,那就用底层命令自己搭。拿 git 和 find 比?搞笑过头了。
    no1xsyzy
        31
    no1xsyzy  
       2020-07-15 16:02:35 +08:00
    @reus #30 明明问题出在 Unix 哲学本身上,为什么要怪罪于一个 (1) 的工具?
    因为 Unix 哲学深植于 worse is better,导致一堆程序需要自己实现大部分 performance-oriented workaround
    这不是一样的么……
    maxbon
        32
    maxbon  
       2020-07-18 16:30:54 +08:00
    勇士,就跟 rm -fr +相对路径一样。rm -fr ../../ ,这种我都不敢用的,一不小心就 GG 了
    movsb
        33
    movsb  
       2020-07-26 21:42:05 +08:00
    find 的表达式是从左往右执行的,其中一个表达式返回 true 后面的就不执行了,-print0 始终返回 true 。所以,结果你知道了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5858 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 01:54 PVG 09:54 LAX 18:54 JFK 21:54
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86