序言
临近周末,小林开始飘了。
写个简单的Bash脚本都不上心了linux通配符,写完连检测都不检测,直接拖到到实体服务器跑。
结果一跑上去,发觉不对劲,如何一个简单脚本跑了10秒还没结束,于是立刻直接ctrl+c一顿操作停掉了运行中的脚本。
接着,习惯性的输入了ls,结果what?找不到ls命令?
顿时背后一凉,慌惊慌张打开了脚本。
发觉问题了,小林我写了个巨蠢的Bug,间接执行了rm-fr/*,这不意味着我删库了?
这台是公司的授权服务器呀,被小林如此一整,公司历史的授权记录和其他重要信息不就丢了?
心中慌得一批的小林,跟同学们说了这件事,同学建议我第一时间上报给leader,不要把删库的事情瞒着。
于是,小林就向leader说了删库事情,本以为会被痛批一顿。
结果leader笑着说:“没事,你先瞧瞧重要的文件还在不在。不过你那么一整,我忽然想起编译服务器半年没备份,我先备份一下我的编译服务器,避免哪天也被大家删库了。”
我:“????”
吃瓜的男子伴,是不是认为小林要删库跑路了?哈哈哈,小林没跑路,反倒是恢复了回去,所以接出来聊聊小林是怎样「从删库到恢复」的。
初探案发觉场
来瞧瞧小林写的垃圾代码,是怎样引起此次的删库。
既然发生了rm-fr/*的现象,那必然new_lic_dir这个变量是空的。
所以造成执行rm-fr$new_lic_dir/*这条句子的时侯,弄成了rm-fr/*删库句子。挺好,凶器找到了。
那为何new_lic_dir会是空的呢?
悉心的男子伴肯定察觉下来了,是由于给new_lic_dir变量形参的时使用了反冒号。
没错,就是反顿号的诱因。
反顿号在LinuxShell命令行中有特殊的涵义:反顿号间的内容,会被Shell先执行。其输出被装入主命令后,主命令再被执行。
也就是说,new_lic_dir的值是${lic_path}/new_license这条命令执行的结果,问题这哪是命令啊,所以肯定返回空值给new_lic_dir变量。
小林写得这么温柔的代码,居然弄成了穷凶极恶的删库代码。
这下诱因是找到了,反顿号应当改成双冒号才对。
小林你真菜呀,这么简单的形参命令都弄错。
哈哈哈,确实菜深度linux,都说了嘛,快国庆了,小林是飘着写这份代码的。
所以习惯性开启程序员内容的第一大武功:crtl+c和crtl+v。
把第一条形参lic_path=`pwd`句子,复制粘贴了,之后只改了变量名,没注意反顿号要更改成双冒号,所以导致了删库的杯具。
保留案发觉场
既然发生了删库的事情,千万不要重启服务器,也不要关掉ssh联接的会话,而是要保留案发觉场,接着查查还剩哪些。
小林,这不是吹大炮嘛?ls都没了,还如何查?
还好此次比较辛运,由于在执行脚本的时侯,第一时间发觉不对劲,立刻斩断了还在运行的脚本,所以并非Linux所有文件都被删掉了。
只要我掐得快,rm-fr/*就干不死我。
尽管ls被删了,但所幸发觉cd命令能够用。
只要cd用得好,它也能用出ls的疗效。很简单,只需cd+Tab键都会手动出现指定目录下的所有文件。
有了cd+Tab键,我们就可以查看每位目录下的文件,于是就可以一步一步来确认什么系统文件被删了。
通过一番的确认和对比后,发觉主要被删掉的有四个目录分别是:
来备考一下前面这四个目录主要是储存了哪些:
/boot都被删掉了,还好小林没有重启服务器,要是重启了服务器,就完犊子了,系统肯定起不来了。
cd命令是在/sin目录下,/sin还完善,所以cd是可以正常使用。
所幸重要的数据库信息和文件都还没删掉,所以小林首要的目标是要恢复/bin、/boot、/dev、/lib这四个目录。
还原文件
因为/bin目录和/lib部份动态文件被删掉,常用的传递文件的形式是难以使用的,如ftp、scp、mount等。
小林摸索了许久,居然发觉wget可以使用,wget命令是在/usr/bin目录,所幸/usr/bin还完善。
于是,用了取巧的方式,先另一台正常的服务器,把/bin目录放在了Web服务器的Web目录,接着通过wget进行下载。
有戏,见到了成功的曙光。
然而新的问题就来了,我下载过来的命令文件,是没有执行权限的。
而chmod命令是在/bin目录的,它同样也被删掉了,没法使用它来给与文件权限。
还在,在网上搜到了一个伟大命令perl,可以通过它来给与文件权限:
perl-e"chmod777,'ls'"
真是个神奇的命令。
好了,这下形参权限问题也解决了,成功在望了。
wget是难以直接把/bin目录下载出来的,只能下载一个文件。
然而小林我不可能一个一个去下载来进行恢复,这得要何年何月才会完成。。。
小林就想到了一个方式:
/bin就这样恢复回去啦,剩余的其他目录也是通过同样的操作恢复了回去。
小林的微笑逐渐恢复了回去,哈哈哈哈哈哈哈哈哈哈哈哈~
遇见rm-fr/*删库风波发生,一定要沉住气,撑住态度!
本次删库风波,之所以小林能辛运的恢复回去,有特别关键两点:
假如以上两点都没做好,服务器恢复的难度就加强了好多,更严重的是周末就无法过了。
防治误执行rm-fr/*
既然rm-fr/*是残暴的凶器,这么防治它是很有必要的,接出来跟你们讨论讨论防治它的几种方案。
1、rm-rf删掉目录时要判定目录
#!/bin/bash
work_path=`pwd`
#假如目录不为空,才执行删掉操作
if[${work_path}!=""];then
rm-fr${work_path}/*
fi
在执行删掉目录操作前,先判定要删掉的目录是否为空,不为空才执行删掉操作。
2、Shell脚本指定set-u
执行脚本的时侯,假如遇见不存在的变量,Bash默认忽视它。
#!/bin/bash
echo$a
echohello
里面代码中,$a是一个不存在的变量,执行结果如下。
$bashtest.sh
hello
可以发觉,echo$a输出了一个空行,Bash忽视了不存在的$a,之后继续执行echohello。
最好是遇见变量不存在,脚本应当报错,而不是一声不响地往下执行。
set-u就拿来改变这些行为,在脚本加上它,遇见不存在的变量都会报错,并停止执行。
#!/bin/bash
set-u
rm-fr$a/*
echohello
运行结果如下:
$bashtest.sh
test.sh:line4:a:unboundvariable
可以看见,由于a是未定义变量,脚本报错了,而且不再执行前面的句子。
3、safe-rm替换rm
safe-rm是一个开源软件工具,这名子听上去就很安全嘛,所以它是拿来取代不太安全的rm。
它可以在/etc/safe-rm.conf中配置路径黑名单,定义什么不能被safe-rm删掉。
我们可以将safe-rm改名为rm,假定定义了/etc/无能被删掉,这么删掉/etc时都会报错:
$rm-rf/etc/
safe-rm:skipping/etc/
4、建立回收站机制
Windows是有回收站的,虽然删掉了,也可以在回收站恢复。
所以linux执行.sql脚本,我们也可以在Linux实现回收站的机制。
实现思路:
删掉文件时,它并不真正执行删掉操作,而是将文件联通到一个特定目录,可以设置定时清理回收站,或则在回收站上面的文件大小达到一定容量时(或则用时间做判定)执行删掉操作以腾出空间。
可以写个Shell脚本替换rm命令,或则在须要删掉文件的时侯使用mv命令将文件联通到回收站。
1)创建回收站目录
mkdir/home/.trash
2)编撰remove.sh脚本,内容如下
3)更改~/.bashrc,用我们自建的remove.sh取代rm命令
aliasrm="sh/home/remove.sh"
4)设置crontab,定期清空垃圾箱,如每晚0点清空垃圾箱:
00***rm-rf/home/.trash/*
5)最后,执行以下命令,使之生效
source~/.bashrc
5、根文件挂载成只读
在/etc/fstab文件,把/文件系统挂载成只读的形式。
其中remount,ro,就表示只读的形式挂载。
只读的形式挂载后,进行删掉操作是未能成功的:
事后反省
涉及到rm-fr命令的代码,要留个心眼,要反复检测,要做好防治误执行rm-fr/*,并在测试机验证完后,再拖到实体机上跑,千万不可大意。
即使的发生了rm-fr/*,要第一时间停掉它,而且要做到三不要:
只要立刻斩断rm-fr/*,它是干不死我们的。
借助当下环境剩有的命令,冷静剖析,是有机会恢复的。
小林如今是一个删过库没跑路的女人了,Goodbye,我们上次见~
-END-
明日书籍推荐
《Python手动化测试实战》从功能测试变革手动化测试的必备修练宝典linux执行.sql脚本,通过300个图解+100个实战案例,全方位提高你的测试能力。
(1)深入浅出:解读与Oracle数据库性能相关的方方面面,囊括Oracle的体系构架及其背后的运行机制。
(2)直击难点:全面解析OracleSQL执行计划和OracleSQL性能剖析与优化。
(3)全新实战:真实有效的实战案例重现Oracle数据库开发过程中的问题及解决思路。
(4)双管齐下:先设定方案,之后从应用角度和数据库角度综合考虑,逐一剖析实现环境。
留言捐书参与方式
分享一下你在学习或则使用Python、Oracle的经验体会,活动截至时获得点赞数最多的前3名获得以上书籍中的任1本,同时我们也将选择2名小金鱼同样获得捐书1本
截至时间:2020年05月26日16:00整
●
●
●
●
●
●