Linux防止“rm -rf /”误操作的方法

  • 2014年06月07日

  •  

--preserve-root 选项

像freebsd, GNU/Linux 这样的系统都有文件系统根目录保护机制,如果没有指定--no-preserve-root参数,GNU rm 将拒绝执行

rm -rf / 这样致命的指令(嗯,其实我没有验证过其效果啦),但只应用于文件名严格为 '/' 的情形,不能阻止

rm -rf /*

避免使用 ./ 前缀

要删除一个目录下的所有内容,不要使用

rm -rf ./* ,更进一步地,不要使用 ./* 来引用当前目录下的所有文件,直接使用 * 即可,这样可以避免写成 /* 或者 / * 这样的悲剧发生。

chattr 设置扩展属性

在需要保护的目录下创建一个文件名比较靠前的文件 0,设置其不可删除

touch /0
chattr +i /0
 这种做法对 -f 选项的rm 命令行无效,其它文件仍然会被删除。

使用 -i 文件赋予命令行中 rm -i 选项

在重要目录下创建 -i 文件

touch -- /-i /usr/-i /bin/-i /sbin/-i /etc/-i /lib/-i /lib64/-i \
/boot/-i /dev/-i /var/-i
 -i 文件并不能阻止

rm -rf /etc/*
rm -rf ./*
 这样的事情发生,因为此时 -i 文件的路径是 /-i, ./-i, 不会被解释成 rm 的选项。 所以前面讲的避免使用 ./ 前缀对于 -i 文件起到作用很重要。

alias rm='rm -I' 并避免使用 -f 选项

因为缺省的 alias 是 rm='rm -i', 所以为了避免删除每个文件都要确认,得使用 -f 选项(如果没有 alias rm='rm -i', 删除多个文件、递归删除都不需要使用 -f 选项)。

rm 的 -I 选项的作用是

prompt once before removing more than three files, or when removing recursively. Less intrusive than -i, while still giving protection against most mistakes

此方法不能避免一次误删除数量少于或等于3个的文件。

此方法可以和上面的创建不能具有 i 扩展属性的文件结合使用。

将 -r -f 选项放在命令行的最后面

这样可以避免路径尚未敲完整时误按 enter 键造成的错误操作。

此方法在使用 GNU coreutils 的系统上可用,在某些unix系统上可能不支持将选项放到命令行的最后。。

使用 safe-rm 替代 rm

Safe-rm is a safety tool intended to prevent the accidental deletion of important files by replacing /bin/rm with a wrapper, which checks the given arguments against a configurable blacklist of files and directories that should never be removed.

Users who attempt to delete one of these protected files or directories will not be able to do so and will be shown a warning message instead:

$ rm -rf /usr
Skipping /usr
 (Protected paths can be set both at the site and user levels.)

可以将 safe-rm 更名为 rm 并放在 $PATH 中比 原rm 程序靠前的位置。一些脚本中使用完全路径/bin/rm则不会受此影响。虽然将 safe-rm 重命名成 rm 有其好处,但平时应该养成尽量避免在命令行中使用 rm 的习惯,在命令行中 safe-rm 的名称来执行安全删除操作,以避免因为依赖伪装成 rm 的safe-rm 导致在没有 safe-rm 的机器上犯错。

The system-wide blacklist lives in /etc/safe-rm.conf and you should probably add paths like these:

/
/etc
/usr
/usr/lib
/var
 The user-specific blacklist lives in ~/.safe-rm and could include things like:

/home/username/documents
/home/username/documents/*
/home/username/.mozilla

建立回收站机制

回收站机制则是另一种思路,它并不真正执行删除操作,而是将文件移动到一个特定目录,可以设置定时清楚回收站,或者在回收站里面的文件大小达到一定容量时执行删除操作(可以选择清空,更保守的做法时设置soft/hard阈值之类的)以腾出空间。

可以写个shell脚本替换rm命令,或者在需要删除文件的时候使用mv命令将文件移动到回收站。

只读挂载

boot文件系统可以设置 noauto,ro 的挂载选项。

防止空变量导致的误删除

在脚本中不要使用

rm -rf $FOO/
执行这样的操作前最好检查变量是否非空,而且不要带后面的/

[[ -n $F00 ]] && rm -rf $FOO

做好备份

这个是王道,不仅可以防止误删,还可以防止其它如硬盘损坏等原因导致的数据丢失。
可以采用dump的增量备份机制,LVM快照,在虚拟化环境中的快照功能等等。

其它

良好的工作习惯是非常重要的,不要过于依赖工具,比如不要因为像 safe-rm 这样的保护机制而放松警惕,否则当你在一台没有那种保护机制的机器上操作时,会因为过于轻率地使用rm命令导致悲剧。另外一点就是不要使用root作为日常工作账号。

我一直以为 rm -rf dir/ 和 rm -rf dir 是不同的,以为前者等价于 rm -rf dir/*, 因为在 rsync 中 dir/ 隐含 dir/*。但是今天发现rm -rf dir/ 是会删除 dir 这个目录的。所以在删除一个目录时,完全没必要使用 dir/ 这样的形式,这样少敲一个键且可以避免误删的风险。

Reference

通过替换linux rm命令防止误删除

How do I prevent accidental rm -rf /*?

+==================================================+

linux中的 rm -rf * 删除文件确实很快,可以如果养成经常用 rm -rf * 这个习惯可就不好了。一不小心就把你重要的资料给删了。。。。 用rm删除的文件是很难恢复的。为了不让 rm -rf * 给我们带来的损失 ,我们可以把 /bin下的 rm改一名字字。然后,在 /bin下建一个名为 rm的bash程序
cd /bin
mv rm rm1
然后
touch rm
vim rm 
/*=============== rm中内容如下
#!/bin/bash
# rm
if echo "$1" |grep \- ;then 
    opation="$1"
    shift
fi

mkdir -p /.trash_all_users
:>/.trash_all_users/.rm_filename.txt
for i in "$@"
do
    time=`date +%m-%d_%H-%M-%S`
    mv "$i" /.trash_all_users/"$i"_"$time"
    echo "$i"_"$time",`pwd`"/$i" >>/.trash_all_users/.rm_filename.txt
done;
===================================    */

再建一个 unrm   用于恢复
/*===================   unrm 内容如下   
#!/bin/bash
# /bin/unrm
file="/.trash_all_users/.rm_filename.txt"
for i in `cat $file `;do    
    mv   `echo "/.trash_all_users/$i"|tr "," " " `
done
:>$file
=========================    */

chmod 755 rm
chmod 755 unrm
chmod 777 /.trash_all_users

最后,每隔一段时间清空一次。清空的时候,就用 cd /.trash_all_users ;rm1 -rf * ,这下删除了可就再也恢复不回来了哦!!!!

#bash_program