起因
最近同事接到一个应急,客户的局域网服务器被中病毒了,影响规模有数千台主机,服务器均为Linux,但均属于不同的发行版,多半为Ubuntu和SuSE,为了能够节省检测和查杀的人力成本,有必要通过工具予以实现。
在选择实现语言的过程中出现了麻烦的事。如果用C语言开发,开发周期过长,而且细粒度语言可能碰到的坑会非常多。如果用Python开发,Ubuntu问题不大,系统一般都会内置,但是SuSE系统就悲剧了,人家默认就没这东西,写出的代码完全无法运行,如果查杀前再需要先装Python运行环境,那还不如手工查杀来的快呢。
经过慎重选择,决定使用“SHELL脚本”来实现,这东西基本每台Linux都会有,不会出现无法运行的情况。碰巧,今天心情不错,就把“SHELL脚本”的一些用法做个汇总,以打消外人对SHELL脚本的误解。
从不只一个人的口中听说过:SHELL只能做些无脑的文件和命令操作,我今天要告诉他们SHELL脚本连病毒的检查及清理都可以实现,还有什么东西能难住它?
SHELL脚本中的技巧和坑
文件特征检测
要查病毒,特征检测是绕不过的,通常思维下Shell脚本对文件内容的处理是比较难搞的,经过一段时间的思考,找到了一条相对稳定的实现方案,如下所示:
整个逻辑的关键代码为 14 行,它涉及到4个命令的使用:
- xxd指令可以将文件内容以16进制编码格式进行输出,此时输出的内容中存在换行符;
- 将上一个结果中的换行符过滤掉,变成一行;
- 使用grep对文件内容进行过滤,过滤规则为41414141特征,这个特征对应的ASCII编码为4个A;
- 用wc指令进行行数统计,如果文件中存在特征,则经过grep过滤后,会有内容输出,即行数不为0。
测试可以用两个文件file1 和file2,其中file2文件有AAAA特征file1无该特征,如下所示:
然后运行脚本将file2文件检测出来,测试结果如下:
变量展开
在“SHELL脚本”编写中,函数定义是一定会经常用到的。对函数进行参数传递时,也经常会遇到变量传递,如下所示:
从func函数的执行效果可知,该函数传入的参数有两个,且第一个参数的值为value1 虽然在函数调用中,是以
func $valueList
这样的方式进行参数传递,但在函数执行的过程中参数内容被展开了,变成了下面的样子
func value1 value2
这和C语言中的宏很像,这个问题我在脚本编写中遇到了多次,每次都会导致极为隐蔽的BUG。其实规避方法很简单,那就是将变量以双引号扩起来即可,如下图所示:
可以看到双引号扩起来后,函数执行时就仅有一个参数了,而且参数内容也是完整的valueList内容了。
SHELL四则运算
没做过SHELL开发的人,经常会忽略SHELL能做四则运算这一事实,让SHELL能做四则运算的关键在于let这个关键字,用法如下所示:
然而能让 shell 中的四则运算正常工作,却需要规避几个重要的坑才行,
- 切忌等号前后均不应有空格,否则你会遇到这样的错误
-
切忌书写let关键字,否则你会遇到这样的错误
可以看到它试图将第9行的 2+3 当作命令去执行,结果就报错了。 - 运算符前后均不应有空格,否则你会遇到这样的错误
函数返回值
准确来说shell脚本的返回值有两种,一种结果代表执行状态,另一种是执行结果。样例代码如下所示:
字符串转数组
在SHELL脚本中是有数组概念的,虽然只有一维数组,但也完全足够日常使用了,如果想要多维数组,只有自己去实现了,相信小伙伴们能够想到些办法,我就不解释了。下面展示一个将列表转为数组的代码,以便大家熟练数组的转换。
循环
除了常见的通过if语句判断循环条件外,shell 中提供了 for…in… 语法糖。代码样例如下所示:
结尾来个小公告
好久没来更新博客了,因为在忙各种总结,同时“蚯蚓2.0(暂定这么个名字吧,我决定给它换个名字)”终于进入最后的集成测试阶段了,上午写完了最后一行功能代码,那一刻我觉得自己又“如来附体”“无所不能”了。
正式公布前,它还需要经历几个步骤,分别有:
- 交互强化,主要解决帮助文本的措辞,以及提高容错能力。
- 平台通配测试,要对各主要系统平台进行通配测试。
- 小范围分发测试,主要是BUG修复,以及不合理的逻辑修改。
- 重定名以及主页开发,每个大版本都要重新命名,并为其配一个主页,2.0当然不会例外。
所以距离正式上线可能还需要2个月左右的时间吧,要做的事情还有很多,要加把劲了。