我如何防止意外rm -rf / *?

我只是偶然地运行rm -rf /* ,但是我的意思是rm -rf ./* (注意斜线后面的星号)。

alias rm='rm -i'--preserve-root默认没有救我,所以这里有没有自动防护措施?


我没有root权限,立即取消了命令,但是在某处或某些地方有一些宽松的权限,因为我注意到我的Bash提示符已经被破坏了。 我不想依赖权限,也不是根(我可以用sudo犯同样的错误),而且我也不想寻找系统中某处缺less文件的神秘错误,所以备份和sudo很好,但是我希望这个具体案例更好。


关于两次思考和使用大脑。 我正在使用它! 但是我正在用它来解决一些涉及10个不同事情的复杂的编程任务。 我深深地沉浸在这个任务中,没有任何权力留下来检查旗帜和path,我甚至没有在命令和论点方面进行思考,我认为就“空当前目标”这样的行动而言,我大脑的不同部分将他们转化为命令,有时会犯错误。 我想让电脑纠正它们,至less是危险的。

    我遵循的技巧之一是在使用rm命令时将#放在开头。

     root@localhost:~# #rm -rf / 

    这可以防止在错误的文件/目录下意外执行rm 。 validation完成后,从头开始删除# 。 这个技巧是有效的,因为在Bash中,以#开始的单词使得该单词和该行上的所有剩余字符被忽略。 所以命令简单地被忽略。

    要么

    如果你想防止任何重要的目录,还有一个窍门。

    在该目录中创build一个名为-i的文件。 如何创build这样一个奇怪的文件? 使用touch -- -itouch ./-i

    现在尝试rm -rf *

     sachin@sachin-ThinkPad-T420:~$ touch {1..4} sachin@sachin-ThinkPad-T420:~$ touch -- -i sachin@sachin-ThinkPad-T420:~$ ls 1 2 3 4 -i sachin@sachin-ThinkPad-T420:~$ rm -rf * rm: remove regular empty file `1'? n rm: remove regular empty file `2'? 

    这里*会将-i扩展到命令行,所以你的命令最终会变成rm -rf -i 。 因此,命令将在删除之前提示。 你可以把这个文件放在你的//home//etc/等等

    要么

    使用--preserve-root作为rm的选项。 在更新的coreutils包中包含的rm中,这个选项是默认的。

     --preserve-root do not remove `/' (default) 

    要么

    使用安全的

    摘自网站:

    Safe-rm是一个安全工具,旨在通过用一个包装器replace/ bin / rm来防止重要文件的意外删除,该包装器将给定的参数针对可configuration的文件和目录的黑名单进行检查,这些文件和目录永远不会被删除。

    试图删除其中一个受保护文件或目录的用户将无法执行此操作,而是显示一条警告消息:

     $ rm -rf /usr Skipping /usr 

    你的问题:

    我只是偶然地运行rm -rf / *,但是我的意思是rm -rf ./*(注意斜线后面的星号)。

    解决scheme: 不要这样做! 按照惯例,不要在path的开头使用./ 。 斜杠不会增加命令的价值,只会造成混淆。

    ./*含义与*相同,所以上面的命令写得更好:

    rm -rf *

    这是一个相关的问题。 我经常看到下面的expression,有人认为FOO被设置为像/home/puppies类的东西。 实际上,我在一个主要软件供应商的文档中看到了这一点。

    rm -rf $FOO/

    但是,如果没有设置FOO ,这将评估为rm -rf / ,它将尝试删除系统上的所有文件。 尾部的斜线是不必要的,因此实践中不要使用它。

    以下将做同样的事情,并且不太可能破坏你的系统:

    rm -rf $FOO

    我很难学习这些技巧。 当我14年前拥有第一个超级用户帐户时,我无意中在shell脚本中运行了rm -rf $FOO/并销毁了一个系统。 另外4位系统pipe理员看着这个,说:'是的。 每个人都这样做一次。 现在这里是你的安装媒体(36软盘)。 去修复它。

    其他人在这里推荐像--preserve-rootsafe-rm这样的解决scheme。 但是,这些解决scheme并不适用于所有Un * xe-varients,并且可能无法在Solaris,FreeBSD和MacOSX上运行。 此外, safe-rm要求您在每个使用的Linux系统上安装附加软件包。 如果你依靠safe-rm ,当你开始一个新的工作,他们没有安装safe-rm时候会发生什么? 这些工具是一个拐杖,依靠已知的默认值并改善您的工作习惯会好得多。

    既然这是“Serverfault”,我想这样说:

    如果你有几十个或更多的服务器,pipe理员/用户组成一个庞大的团队, 有人rm -rfchown错误的目录。

    您应该制定一个计划,尽可能减less受影响的服务的MTTR。

    最好的解决scheme包括改变你的习惯,不要直接使用rm

    一种方法是先运行echo rm -rf /stuff/with/wildcards* 。 检查通配符的输出是否合理,然后使用shell的历史logging执行没有echo的前一个命令。

    另一种方法是限制echo命令的情况下,它是非常明显的东西你会删除。 而不是删除目录中的所有文件,删除目录并创build一个新的目录。 一个好方法是将现有目录重命名为DELETE-foo ,然后用适当的权限创build一个新的目录foo ,最后删除DELETE-foo 。 这种方法的一个好处是,input到历史logging中的命令是rm -rf DELETE-foo

     cd .. mv somedir DELETE-somedir mkdir somedir # or rsync -dgop DELETE-somedir somedir to preserve permissions ls DELETE-somedir # just to make sure we're deleting the right thing rm -rf DELETE-somedir 

    如果你真的坚持删除一堆文件,因为你需要保留这个目录(因为它必须一直存在,或者因为你没有权限来重新创build它),把这些文件移到不同的目录下,然后删除那个目录。

     mkdir ../DELETE_ME mv * ../DELETE_ME ls ../DELETE_ME rm -rf ../DELETE_ME 

    按Alt + 键。)

    从里面删除一个目录会很有吸引力,因为rm -rf . 因此缺less拼写错误的风险较低。 不幸的是,典型的系统不会让你这样做。 你可以使用rm -rf -- "$PWD"来代替错别字,但是大部分都会导致没有任何结果。 注意这会在你的shell历史中留下一个危险的命令。

    只要你可以,使用版本控制。 你不是rm ,你是cvs rm或其他什么的,那是可以撤销的。

    在运行rm之前,Zsh提供了一个参数列出目录中的所有文件: rm_star_silent (默认为on)在执行rm whatever/*之前会提示rm whatever/* ,而rm_star_wait (默认为closures)会增加10秒的延迟,无法确认。 如果您打算删除某个目录中的所有文件,这是有限的使用,因为您已经期待提示。 它可以帮助防止类似rm foo *错误。

    还有更多的解决scheme需要更改rm命令。 这种方法的一个限制是,有一天你将会在一台真正的rm机器上,你会自动调用rm ,在你期待确认的时候是安全的,接下来你将恢复备份。

    你可以随时做一个别名,如你所说:

     what_the_hell_am_i_thinking() { echo "Stop." >&2 echo "Seriously." >&2 echo "You almost blew up your computer." >&2 echo 'WHAT WERE YOU THINKING!?!?!' >&2 echo "Please provide an excuse for yourself below: " read echo "I'm sorry, that's a pathetic excuse. You're fired." sleep 2 telnet nyancat.dakko.us } alias rm -fr /*="what_the_hell_am_i_thinking" 

    您也可以将它与命令行的twitter客户端集成,以提醒您的朋友,您通过以rm -fr /*作为根目录擦除硬盘,几乎蒙羞。

    是的:不要以root身份工作,在演戏之前总是三思而后行。

    另外,看看像https://launchpad.net/safe-rm

    在这个主题中有一些非常糟糕的build议,幸运的是大部分都被拒绝了。

    首先,当你需要成为根,成为根 – sudo和各种别名技巧会让你虚弱。 更糟的是,他们会让你不小心。 学习以正确的方式做事,停止依靠别名来保护你。 有一天,你会得到一个没有你的训练车轮和炸毁的东西的根。

    其次 – 当你拥有根源的时候,把自己想象成驾驶着一辆满载学童的巴士。 有时候你可以在收音机里听到歌曲,但是有时你需要双向观看,放慢速度,仔细检查你的镜子。

    第三 – 你几乎没有真的必须rm -rf – 更有可能你想mv something something.bakmkdir _trash && mv something _trash/

    第四 – 总是在你之前是你的通配符 – 没有什么东西在看东西之前永远摧毁它。

    防止意外rm -rf /*最简单的方法是避免使用rm命令! 其实我一直很想运行rm /bin/rm彻底摆脱命令! 不,我并不是一个开玩笑的人。

    而是使用find命令的-delete选项 ,但在删除文件之前,我build议您先预览一下您将要删除的文件:

     find | less 

    请注意,在现代版本的find如果省略目录名称,则会隐式使用当前目录,所以上面的内容相当于:

     find . | less 

    一旦你确定这些是你想要删除的文件,你可以添加-delete选项:

     find path/to/files -delete 

    因此,不仅使用起来更安全,而且更具有performance力 ,所以如果只想删除与特定模式匹配的目录层次结构中的某些文件,则可以使用类似这样的expression式进行预览,然后删除这些文件:

     find path/to/files -name '*~' | less find path/to/files -name '*~' -delete 

    除了一个更安全的rm之外,还有很多很好的理由来学习和使用它,所以如果你花时间学习使用find ,那么你会感谢你。

    这是我在rm上专门针对正则expression式的标准,但是在这种情况下它会为你节省开支。

    我总是使用echo foo*/[0-9]*{bar,baz}*来查看正则expression式匹配的内容。 一旦我有了输出,然后我回到命令行编辑,并改变echo rm -rf 。 我从来没有,使用rm -rf在未经testing的正则expression式

    解决这个问题的办法是定期进行备份。 任何时候,你产生的东西,你不想冒险失去,支持它。 如果你经常发现备份太痛苦,那就简化这个过程,这样并不痛苦。

    例如,如果您使用源代码,请使用像git这样的工具来镜像代码并在另一台机器上保留历史logging。 如果你在文档上工作,有一个脚本rsync你的文件到另一台机器。

    看起来降低这种风险的最好方法是像大多数GUI一样进行两阶段删除。 也就是说,把rmreplace成一些东西移动到垃圾目录(在同一个卷上)。 然后在足够的时间过去之后清理垃圾,注意到任何错误。

    在这里的Unix StackExchange上讨论了一个这样的工具垃圾邮件。

    避免此类错误的一个重要因素是不要使用root帐户login。 当您使用普通的非特权用户login时,您需要为每个命令使用sudo 。 所以,你应该更加小心。

    这可能会很复杂,但是你可以在SELinux中设置angular色 ,这样即使用户通过sudo su – (或简单的su)变成root,删除文件的能力也是有限的(你必须直接以root身份login才能删除文件)。 如果你正在使用AppArmor,你可能会做类似的事情。

    当然,另一个解决scheme是确保你有备份。 🙂

    当我recursion删除一个目录时,我把-r-f如果适用的话)放在命令的末尾 ,比如rm /foo/bar -rf 。 这样,如果我不小心按Enter键,而没有键入整个path,命令不recursion,所以它可能是无害的。 如果我试图在/foo之后input斜杠来回车,我写了rm /foo而不是rm -rf /foo

    这在使用GNU coreutils的系统上效果很好,但其他某些Unix上的实用程序不允许将选项放在最后。 幸运的是,我并不经常使用这样的系统。

    避免使用globbing 。 在Bash中,你可以设置noglob 。 但是,当你转向一个没有设置noglob的系统时,你可能会忘记这一点,并继续进行下去。

    设置noclobber以防止mvcp破坏文件。

    使用文件浏览器进行删除。 某些文件浏览器提供了一个垃圾箱(例如, Konqueror )。

    另一种避免混淆的方法如下。 在命令行中,我echo filenamepattern >> xxx 。 然后使用Vim或vi编辑文件,以检查哪些文件将被删除(请注意filenmates中的文件名模式字符),然后使用%s/^/rm -f/将每行转换为删除命令。 来源xxx。 通过这种方式,您可以在执行之前查看每个将要删除的文件。

    将文件移动到“attic”目录或tarball。 或者使用版​​本控制(如前所述)。

    在执行rm -rf *之前,ZSH要求我(默认)。

    chattr之外,让root运行这样的命令并没有太多的保护措施。 这就是为什么在运行特权时适当的组和谨慎的命令是重要的。

    下次; 将您计划删除的文件范围缩小 – 从rm -rf省略“f”,或者使用find并将其传递给xargs rm

    其他命令的一些安全别名,以防止类似的灾难,在这里find:

     # safety features alias cp='cp -i' alias mv='mv -i' alias rm='rm -I' # 'rm -i' prompts for every file alias ln='ln -i' alias chown='chown --preserve-root' alias chmod='chmod --preserve-root' alias chgrp='chgrp --preserve-root' 

    注意大写字母-I ,它与-i不同:

    在删除三个以上的文件之前提示一次,或者recursion删除。 比-i更less侵入,同时仍保护大多数错误

    我通常使用-v标志来查看正在被删除的内容,如果我有丝毫怀疑,有机会很快删除它。 不是真正的防止rm的方法,但这可以有效地限制损坏,以防出现问题。

    我在基于Unix的机器上的删除过程如下。

    • 在terminal窗口中inputls /path/to/intented/file_or_directory ,然后按return Tab (或Tab ,根据需要),查看文件列表。

    如果一切看起来不错,

    • 单击up arrow键,再次从terminal历史logging中ls /path/to/intented/file_or_directory

    • rmrm -rrm -rfreplacels ,根据需要。 我个人不喜欢用-f标志。

    这个validation过程还可以防止在我开始执行这个过程之前,过早执行rm命令,这是发生在我身上的事情。

    如果你现在没有心情习惯新的习惯,那么.bashrc/.profile是添加一些testing来检查你是否要做一些愚蠢的事情的好地方。 我想了一个Bash函数,我可以grep一个模式,可能会毁了我的一天,想出了这个:

     alias rm='set -f; myrm' #set -f turns off wildcard expansion need to do it outside of #the function so that we get the "raw" string. myrm() { ARGV="$*" set +f #opposite of set -f if echo "$ARGV" | grep -e '-rf /*' \ -e 'another scary pattern' then echo "Do Not Operate Heavy Machinery while under the influence of this medication" return 1 else /bin/rm $@ fi } 

    关于它的好处是,它只是Bash。

    这种forms显然不够通用,但我认为它有潜力,所以请张贴一些想法或意见。

    嘿嘿(没有经过检验,有点脸色!):

     $ cat /usr/local/bin/saferm #! /bin/bash /bin/ls -- "$@" echo "Those be the files you're about to delete." echo "Do you want to proceed (y/N)?" read userresponse if [ "$userresponse" -eq "y" ]; then echo "Executing...." /bin/rm -- "$@" fi 

    接着:

     alias rm="/usr/local/bin/saferm" 

    实际上,在使用glob执行这样的操作之前,你应该有一个心理上的停顿,无论你是以root身份运行,为它预先添加“sudo”等等。你可以在同一个glob上运行“ls”但是,在精神上,你应该停下来一秒钟,确保你已经键入你想要的东西,确定你想要的是你想要的东西等等。我想这是主要通过摧毁第一年一个Unix的SA,就像热炉是一个好老师告诉你炉子上的东西可能很热。

    并确保你有良好的备份!

    此外,不是作为一种保护措施,而是作为一种方法来找出哪些文件被删除之前,你击中^ C,你可以使用locate数据库(当然只有当它被安装和幸存rm

    我从这个博客文章了解到

    只需使用ZFS来存储您需要抵制意外删除的文件,并有一个守护进程:

    • 定期制作这个文件系统的快照
    • 删除旧的/不必要的快照。

    如果文件被删除,覆盖,损坏,无论如何,只要将文件系统回滚到最后一个快照的克隆,就完成了。

    Sadly, I cannot leave a comment above due to insufficient karma, but wanted to warn others that safe-rm is not a panacea for accidental mass-deletion nightmares.

    The following was tested in a Linux Mint 17.1 virtual machine (warning to those unfamiliar with these commands: DON'T DO THIS! Actually, even those familiar with these commands should/would probably never do this to avoid catastrophic data loss):

    Text version (condensed):

     $ cd / $ sudo safe-rm -rf * $ ls bash: /bin/ls: No such file or directory 

    Image version (full):

    在这里输入图像描述

    not so much an answer but a tip, i always do rm (dir) -rf not rm -rf (dir) ie: don't go nuclear until the last possible moment.

    It helps mitigate situations in which you fat finger the dir name in such a way that it's still a valid deletion, such as slipping and hitting the enter key.

    I like the windows approach of the recycle bin.

    I usually create a directory named "/tmp/recyclebin" for everthing I need to delete:

     mkdir /tmp/recyclebin 

    And never use rm -rf, I always use:

     mv target_folder /tmp/recyclebin 

    Then later on, I empty the recyclebin using aa script or manually.

    I think this is a powerful prevention tip, with * expansion shortcut in shell:

    First, type rm -rf * or rm -rf your/path/* , DON'T type Enter key. (of course, you should have a habit of caring not to press Enter fast/accidentally when using rm -rf )

    Then, press Alt-Shift-8 (ie Alt-Shift-* ) to expand the "*" wildcard explicitly in bash. This also avoid re-entering a "rm -rf *" command when navigating the history.

    Finally, after checked the expansion has the right files/directories, press Enter.

    完成。