GitLab 的惨剧让我造了个防 rm 的轮子: rm-protection - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
discrete
V2EX    分享创造

GitLab 的惨剧让我造了个防 rm 的轮子: rm-protection

  •  
  •   discrete 2017 年 2 月 3 日 7141 次点击
    这是一个创建于 3263 天前的主题,其中的信息可能已经有所发展或是发生改变。

    rm-protection logo

    rm-protection

    PyPi Downloads PyPiversion Wheel python version

    GitLab 的惨剧想必大家都知道了:rm -rf了生产服务器上的数据库。常在河边走,哪能不湿鞋。即便是再认真,总是有失误的风险。

    现在网上已经流行了数种方法: rm -i , trash-cli 等等。rm -i 显然并不实用:想必没人能忍受每个文件都被问一次?况且就 GitLab 的情况,rm -i并不能起保护作用。trash-cli相当于启用了回收站,但是这又会带来一些小麻烦(比如在磁盘被 log 挤爆的情况下)。

    rm-protection 则采取了一种全新的思路:由用户自行设置一个安全问题来保护文件,在删除时询问相应的问题。想象一下,若 YP 在执行删除时突然被问一句:「 Which server are you on? 」,还会出现这样的惨剧吗?

    快速开始

    rm-protection 几乎完全兼容rm,因此可以作为 alias 使用。

    1. 从 PyPi 中安装并为 rm-p 创建 alias 。

      pip install rm-protection & alias rm="rm-p"

    2. 使用 protect 命令保护你想要保护的文件或者文件夹。

    3. Happy rm-ing!

    原理

    rm-protection 获取 arguments 后,会逐一检测是否存在 .<filename>.rm-protection 文件。若存在,则询问用户,否则将不再传递这个 argument 。安全的 argument 将被传递给 rm 进行删除。

    栗子:

    Basic usage

    它也能保护批量的递归删除:

    Recursive protection

    与其他工具的对比

    参见 GitHub 中的表格

    未来?

    若是这个工具能被推广使用,团队协作之间可以大有功用。在软件、文件分发时,分发者可以提前保护文件防止误删。在开发和部署时也可提前保护文件,防止在生产环境中的误删。

    贡献

    Github 欢迎 PR, 提 Issue 或者 Star :)

    第 1 条附言    2017 年 2 月 4 日

    FAQ

    使用栗子?

    rm -rf database 「你删的是啥数据库」 「测试」 「滚!」 

    简单问题复杂化?

    在特定的场合复杂化我觉得是有益的,比如 GitHub 会在你删除 repo 的时候让你确认 repo 的名字。 事实上 rm-protection 并不影响日常操作。只有当遇到你特定保护的文件时才会提示并提供尽可能的保护。

    rm -i 或者 alias rm="mv" 又或者 trash,下一题?

    每个文件都问,你受得了(当然取决于个人了,我是受不了)?那么你听说过「狼来了」的故事吗?yes | rm -i trash 类的方案并不能从源头上解决问题,当你想释放空间的时候,很容易随手就清空了垃圾桶。

    已经有 XXX 了,好处在哪?

    就我所知除了 Safe-rm 之外,没有类似机制的轮子出现。你也可以看看这里与其他机制的对比:https://github.com/alanzchen/rm-protection/blob/master/README.md#comparison-with-alternative-methods

    我去 Python 3? 你搞笑?

    嘛确实不太合适(逃。其实我完全不 care 到底有没有人用我的 implementation,唯一想做的是向社区提供这么一个机制的提案。

    若是社区能接受,这轮子很快可以被移植到任何语言或者任何平台,甚至被包括在 GNU coreutils 里。唯一需要统一的是,是否能够接受 .rm-protection 这样的保护机制。

    36 条回复    2017-02-05 14:59:28 +08:00
    qiuai
        1
    qiuai  
    PRO
       2017 年 2 月 3 日
    如果是为了服务器多的情况下准备的,为什么不直接设置问题为服务器的名字.
    比如提前在文件中定义服务器的名字为 Prod-1
    那么删除的时候要输入 Prod-1.如果要删除 2.那么不会去输入-1 吧?
    如果输入了-2..那就可以直接拒绝了嘛...

    弄一个问题上去,好像有点复杂?
    jingniao
        2
    jingniao  
       2017 年 2 月 3 日 via Android
    其实我觉得如果给 rm 添加个功能,读取配置文件避开
    jingniao
        3
    jingniao  
       2017 年 2 月 3 日 via Android
    重要文件,如果要删除,加个参数
    discrete
        4
    discrete  
    OP
    &nsp;  2017 年 2 月 3 日
    @qiuai 你确实可以设置为问服务器的名字呀。问题和答案都是用户在保护文件时设定的。在 Prod-1 上你的回答应该是 Prod-1 ,在 Prod-2 上应该是 Prod-2 。

    与丢失重要文件的相比,我觉得问一个问题的时间挺值的。
    discrete
        5
    discrete  
    OP
       2017 年 2 月 3 日
    @jingniao 这个轮子已经有了,叫 Safe-rm 。相比之下我觉得 rm-protection 的方式更加灵活一点。假定你不问问题的话,加个参数还不是顺手事情?(想象一下 YP 的状况。
    Akagi201
        6
    Akagi201  
       2017 年 2 月 3 日
    建议用 bash 重写, 不依赖任何环境.
    discrete
        7
    discrete  
    OP
       2017 年 2 月 3 日
    @Akagi201 这种轻量级的程序确实应该用 bash 写……不过现在哪台机器上没个 python 呢
    不过当然欢迎各种语言的 implementation 。只要 .rm-protection 这个格式互相能兼容就行。
    snnn
        8
    snnn  
       2017 年 2 月 3 日 via Android
    然后硬盘爆了,数据库写入失败,挂掉了
    xuboying
        9
    xuboying  
       2017 年 2 月 3 日
    300G 的数据复制一下,也没多久时间,关键还是要做好备份啊
    rm 再小心还是会有错误的时候。
    问题的关键点还是备份做的不好啊
    Doubear
        10
    Doubear  
       2017 年 2 月 4 日   1
    which server are you on?

    ???

    [我不是在测试环境么???]

    > dev server

    ……

    [卧槽哪来那么多文件?!!糟糕这尼玛不是测试服……]

    《 MySQL 从删库到跑路》
    chu1337
        11
    chu1337  
       2017 年 2 月 4 日
    ~ grep trash .zshrc
    alias trash='gvfs-trash'
    cuebyte
        12
    cuebyte  
       2017 年 2 月 4 日
    @discrete 你好意思……你的是 python3
    yangqi
        13
    yangqi  
       2017 年 2 月 4 日
    你这个显然解决不了类似这次 gitlab 的问题。人家不是误删文件,而且误以为自己在 slave 机器上,结果是在主机上。

    即使有了各种确认也没用
    em70
        14
    em70  
       2017 年 2 月 4 日
    @yangqi 我觉得楼主的方案可以解决,因为会问你当前操作机器的名字,你以为在 slave,输入就是错的,不执行
    yangqi
        15
    yangqi  
       2017 年 2 月 4 日
    @em70 那要看问题是什么了,如果你问了机器名字,下次我文件夹搞错了,误以为在别的文件夹咋办
    cxbig
        16
    cxbig  
       2017 年 2 月 4 日
    我们家是在 PS1 上直接加机器代号, admin 、 backend 、 frontend-1~x 。根本不会弄混。
    WildCat
        17
    WildCat  
       2017 年 2 月 4 日
    SharkIng
        18
    SharkIng  
       2017 年 2 月 4 日
    显然这个也不能完全解决问题, Gitlab 的情况是程序员太累,以为自己在 db2 结果实际是 db1. 即使有这么个问题也有可能因为太累输错之类的。
    eccstartup
        19
    eccstartup  
       2017 年 2 月 4 日
    叫 `rm-gitlab` (逃
    deamwork
        20
    deamwork  
       2017 年 2 月 4 日 via Android
    loading
        21
    loading  
       2017 年 2 月 4 日 via Android
    简单问题复杂化,大师级!
    discrete
        22
    discrete  
    OP
       2017 年 2 月 4 日 via iPhone
    @SharkIng 当你必须输入 I'm going to delete production database 的时候难道还不会心里一惊 2333

    当然了不可能所谓完全解决问题,只是试图以最小的日常影响(比如与 rm -i 相比)做到最大的保护。
    ayayui
        23
    ayayui  
       2017 年 2 月 4 日
    rm 列出要删除的文件,确认后才删除。
    phrack
        24
    phrack  
       2017 年 2 月 4 日 via Android
    也许允许人犯一些错误更好,不然世界就少了乐趣和故事了。
    discrete
        25
    discrete  
    OP
       2017 年 2 月 4 日
    @loading 在特定的场合复杂化我觉得是有益的,比如 GitHub 会在你删除 repo 的时候让你确认 repo 的名字。

    这个工具同理,不会影响你 rm 的日常操作,但是在删除极其重要的文件时提供尽可能的保护。
    discrete
        26
    discrete  
    OP
       2017 年 2 月 4 日
    @cuebyte 嘛确实……(捂脸逃(其实当时不用 python2 只是因为 raw_input() 的问题,加个判断就兼容了。
    discrete
        27
    discrete  
    OP
       2017 年 2 月 4 日
    @yangqi 所以最终还是要问对的问题,比如:
    「你删的是啥数据库」
    「测试」
    「滚!」
    lanxyou
        28
    lanxyou  
       2017 年 2 月 4 日
    批量删除的时候会不会把保护文件先删除了?
    discrete
        29
    discrete  
    OP
       2017 年 2 月 4 日
    @lanxyou 不会,会提前检索保护文件。
    gfexfizv
        30
    gfexfizv  
       2017 年 2 月 4 日 via Android
    可以 alias rm 为 move ,移动到一个垃圾文件夹里面
    harry890829
        31
    harry890829  
       2017 年 2 月 4 日
    用 alias 重定义 rm 啊,改为 move ,然后丢到垃圾文件夹,定期清理垃圾文件夹就好了
    finian
        32
    finian  
       2017 年 2 月 4 日   1
    稍微有点复杂了,不如 trash 的方案来得简单。不过这些方案都无法彻底避免杯具,人和流程都是不可靠的,唯有使用自动化工具才能最大程度地避免失误
    sox
        33
    sox  
       2017 年 2 月 4 日 via Android
    npm i -g trash-cli
    alias rm=“ trash ”
    discrete
        34
    discrete  
    OP
       2017 年 2 月 4 日
    @finian
    @sox
    @gfexfizv

    trash 类方案确实是我之前见过最好的。
    但是 GitLab 让我想起了另外的情况:想象一下空间被 spam 挤爆(类似 GitLab ),大概是清空垃圾箱之后才 Oh shit 吧。在图形界面里,还不是有误删垃圾桶的情况发生?
    qianguozheng
        35
    qianguozheng  
       2017 年 2 月 5 日
    例子中的 gif 图片用什么工具获得的?
    discrete
        36
    discrete  
    OP
       2017 年 2 月 5 日 via iPhone
    @qianguozheng macOS 自带 QuickTime 录屏,然后 Google 里随便找了一个在线的视频转 gif 工具。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2938 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 13:52 PVG 21:52 LAX 05:52 JFK 08:52
    Do have faith in what you're doing.
    ubao msn 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