今天做了一件非常糟糕的事情, 由于一个玩笑导致朋友用 rm
误删了很多重要的文件。
起初是因为印象里 Mint 中 sudo rm -rf /
这个指令不会被执行, 以为 macOS 中也是这样, 但很快就被现实打脸了。
为了防止类似的悲剧再次发生, 我也开始思考怎样避免这种危险的操作 (除了管好我的嘴之外)。
safe-rm
第一种最简单的方法, 安装 safe-rm, 你可以在它的官方网站中下载安装并查看相关的说明文档。
它的使用十分简单, 下载并解包后, 复制 safe-rm
文件到 /usr/bin
路径, 并配置到 $PATH
靠前的位置。
$ cp safe-rm /usr/bin/safe-rm
export PATH="/usr/bin/safe-rm:$PATH"
(此处 PATH
的配置仅为示例, 请根据你的实际情况修改)
你可以通过 safe-rm
指令使用它, 此外, 虽然我并不推荐, 但你的确可以通过 alias rm='safe-rm'
来延续你输入 rm
的习惯。
但是在使用这些指令前, 务必要将重要的路径加入 safe-rm
黑名单。
- 对于整个计算机的所有用户, 你可以配置
/etc/safe-rm.conf
文件, 你可能需要sudo
提升权限才能进行保存 - 对于当前用户, 你可以配置
~/.config/safe-rm
文件
在黑名单的配置文件中加入类似下面格式的内容:
/
/etc
/usr
/usr/lib
/var
其中每一行代表一个受保护的路径, 出现在这里的路径, 在使用 safe-rm
删除时将会被跳过:
$ safe-rm -rf /
safe-rm: skipping /
不过, 这仍旧不能阻止使用 /bin/rm
来进行删除的操作。
-i
或者, 你可以为 rm
指令添加 -i
选项, 再删除时向你确认。
如果担心自己忘记, 你可以为 rm
创建别名:
$ vi ~/.bashrc
alias rm='rm -i'
$ source ~/.bashrc
同时, 在重要的路径下创建名为 -i
的文件, 例如:
touch -- /-i /usr/-i /bin/-i /sbin/-i /etc/-i
但是, -i
文件并不能阻止形如 rm -rf ./*
、rm -rf /etc/*
的指令。
chattr
在重要的路径下创建一个排名靠前的文件 0
, 并设置不可删除:
$ touch /0
$ chattr +i /0
但需要注意的是, 这对 -f
选项是无效的, 其它文件依旧会被删除。
回收站机制
此外还可以尝试使用脚本做一些变通, 例如为准备一个回收站功能, 使用 rm
时不直接删除, 而是移入回收站。
举个例子, 首先我们新建一个 .sh
脚本:
$ vi ~/.saferm.sh
将下面的脚本内容写入:
TRASH_DIR="/Users/ezra/.rmtrash"
for i in $*; do
STAMP=`date +%s`
fileName=`basename $i`
mv $i $TRASH_DIR/$fileName.$STAMP
done
其中 /Users/ezra/.rmtrash
是回收站路径, 依据你的实际情况进行修改即可。
接着, 为 rm
创建别名:
$ vi ~/.bashrc
依据情况加入:
alias rm='/Users/Meniny/.saferm.sh'
保存退出, 重启终端或执行 source ~/.bashrc
。
你可以进行一些测试:
$ touch 1.txt
$ rm 1.txt
$ ls -a ~/.rmtrash
. .. 1.txt.1481211880
当然, 实际使用中我们经常用到 rm
的各种选项, 删除文件夹也是很平常的事情, 那么要用到的脚本将远非如此简单, 此处仅为示例。
防止空变量
前一段时间网络上流传一个类似的事件, 在执行 rm -rf $FOO/
时变量为空, 导致直接执行了 rm -rf /
。
对于这种情况, 一定要做好预防, 务必要对变量进行检查:
[[ -n $F00 ]] && rm -rf $FOO
总而言之
总而言之, 并没有十分完美的方案来阻止 rm
误操作, 很大程度上依旧取决用操作习惯。