写了个Bug,误执行rm -fr /*,瞬间背后一凉( 三 )


  • 发现脚本执行不正常 , 果断立马的掐断它 , 没有造成重要的数据库信息被删除 , 如果掐断的时候再晚一点 , 可能就真没了 。
  • 发现常用命令无法使用的时候 , 没有重启服务器 , 不然服务器就起不来了 , 也没有关闭 SSH 会话 , 不然无法在重新连接 SSH 会话了 , 也就无法进行操作了 。
如果以上两点都没做好 , 服务器恢复的难度就加大了很多 , 更严重的是五一节就没的过了 。
写了个Bug,误执行rm -fr /*,瞬间背后一凉
本文插图

预防误执行 rm -fr /*
既然 rm -fr /* 是残忍的凶器 , 那么预防它是很有必要的 , 接下来跟大家讨论讨论预防它的几种方案 。
方案一:rm -rf 删除目录时要判断目录
#!/bin/bash work_path=`pwd` #如果目录不为空 , 才执行删除操作 if [ ${work_path} != '''' ];then rm -fr ${work_path}/* fi在执行删除目录操作前 , 先判断要删除的目录是否为空 , 不为空才执行删除操作 。
方案二:Shell 脚本指定 set -u
执行脚本的时候 , 如果遇到不存在的变量 , Bash 默认忽略它 。
#!/bin/bash echo $a echo hello上面代码中 , $a 是一个不存在的变量 , 执行结果如下 。
$ bash test.sh hello可以发现 , echo $a 输出了一个空行 , Bash 忽略了不存在的 $a , 然后继续执行 echo hello 。
最好是遇到变量不存在 , 脚本应该报错 , 而不是一声不响地往下执行 。
set -u 就用来改变这种行为 , 在脚本加上它 , 遇到不存在的变量就会报错 , 并停止执行 。
#!/bin/bash set -u rm -fr $a/* echo hello运行结果如下:
$ bash test.sh test.sh: line 4: a: unbound variable可以看到 , 因为 a 是未定义变量 , 脚本报错了 , 并且不再执行后面的语句 。
方案三:safe-rm 替换 rm
safe-rm 是一个开源软件工具 , 这名字听起来就很安全嘛 , 所以它是用来替代不太安全的 rm 。
它可以在 /etc/safe-rm.conf 中配置路径黑名单 , 定义哪些不能被 safe-rm 删除 。
我们可以将 safe-rm 更名为 rm , 假设定义了 /etc/ 无能被删除 , 那么删除 /etc 时就会报错:
$ rm -rf /etc/ safe-rm: skipping /etc/方案四:建立回收站机制
Windows 是有回收站的 , 即使误删了 , 也可以在回收站恢复 。 所以 , 我们也可以在 Linux 实现回收站的机制 。
实现思路:
  • 删除文件时 , 它并不真正执行删除操作 , 而是将文件移动到一个特定目录 , 可以设置定时清除回收站 , 或者在回收站里面的文件大小达到一定容量时(或者用时间做判断)执行删除操作以腾出空间 。
  • 可以写个 Shell 脚本替换 rm 命令 , 或者在需要删除文件的时候使用 mv 命令将文件移动到回收站 。
① 创建回收站目录
mkdir /home/.trash ② 编写 remove.sh 脚本 , 内容如下:
写了个Bug,误执行rm -fr /*,瞬间背后一凉
本文插图

③ 修改 ~/.bashrc ,用我们自建的 remove.sh 替代 rm 命令:
alias rm=''sh /home/remove.sh'' ④ 设置 crontab , 定期清空垃圾箱 , 如每天 0 点清空垃圾箱:
0 0 * * * rm -rf /home/.trash/* ⑤ 最后 , 执行以下命令 , 使之生效:
source ~/.bashrc方案五:根文件挂载成只读
在 /etc/fstab 文件 , 把 / 文件系统挂载成只读的方式 。
写了个Bug,误执行rm -fr /*,瞬间背后一凉
本文插图

其中 remount,ro , 就表示只读的方式挂载 。
只读的方式挂载后 , 进行删除操作是无法成功的:


推荐阅读