很多筒子问我如何能够写出能用的shell脚本
这事其实不难,只要按照以下思路进行就行了
1 把复杂的问题简单化,模块化
2 写出每个模块的伪码
3 组装你的模块
4 写出shell code
5 测试
这事看起来很简单,做起来。。。。。 其实也不难,so easy!
大多数人都是因为害怕所以不敢开始仅次而已,所以筒子们开始吧,从现在开始就动手写你的shell吧
你会喜欢上这工作的!
我们现在就来分析需求统计apache的内存使用量
apache的内存使用量数据如何获得呢?
这事就是硬功夫了,要写shell你得多linux操作系统了解,数据得从/proc/$apachepid/smaps里面获得,对里面的字段进行统计分类来获得。
apache的pid如何获得?
- [root@www conf]# ps -eo user,pid | grep '^apache'
- apache 12160
- apache 12161
- apache 12162
- apache 12163
- apache 12164
- apache 12165
- apache 12166
- apache 12167
顺着这个思路就可以想到用awk来解决,用awk的数组就可以了
- [root@www conf]# awk ' $3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}' /proc/12160/smaps Shared_Clean: 628 kB Pss: 378 kB Swap: 0 kB Shared_Dirty: 2508 kB Size: 19796 kB Private_Dirty: 152 kB Private_Clean: 0 kB Rss: 3288 kB
apache的进程又不是一个,很多个,如何收集所有进程信息呢?
用个循环就可以了,先把apache的pid放到一个数组里面,然后在找个数组里面循环执行awk统计
- APACHEPID=($(ps -eo user,pid | awk '$1~"^apache"{print $2}'))
- #设定数组变量APACHEPID并把获得apache-pid复制给这个数组
- echo "apache total process: ${#APACHEPID[@]}"
- #数组里面元素的个数,就是apache进程的总数
- for pid in ${APACHEPID[@]}
- do
- echo $pid:
- awk ' $3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}' /proc/$pid/smaps
- done &> /tmp/apachemem
- #在数组里面循环执行awk统计,并把结果放入到/tmp/apachemem临时文件内
最后还可以把这个临时文件输入,如果您愿意,ok,现在这个脚本总体就是这个样子了
- #!/bin/bash
- APACHEPID=($(ps -eo user,pid | awk '$1~"^apache"{print $2}'))
- echo "apache total process: ${#APACHEPID[@]}"
- for pid in ${APACHEPID[@]}
- do
- echo $pid:
- awk ' $3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}' /proc/$pid/smaps
- done &> /tmp/apachemem
- echo "apache total memsum:"
- awk '$3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}' /tmp/apachemem
- echo "delete tmp file!"
- rm -fr /tmp/apachemem
怎么样,简单吧!
但是这样的脚本看起来就“很挫”,我们把它变得专业点,也是大家以后养成好的编码习惯,用一种函数编程的思想去写code。
- #!/bin/bash
- TMPFILE=/tmp/apachemem
- #get apache pid
- APACHEPID=($(ps -eo user,pid | awk '$1~"^apache"{print $2}'))
- echo "apache total process: ${#APACHEPID[@]}"
- #define memtotal
- memtotal() {
- filename=$1
- awk ' $3 ~ "kB" { sum[$1] += $2} END {for (key in sum) print key, sum[key]" kB"}' $filename
- }
- #get every pid memtotal into tmpfile
- for pid in ${APACHEPID[@]}
- do
- echo $pid:
- memtotal /proc/$pid/smaps
- done &> $TMPFILE
- #get apache total memsum
- echo "apache total memsum:"
- memtotal $TMPFILE
- #delete tmpfile
- echo "delete tmp file!"
- #rm -fr /tmp/apachemem
这里把统计的过程设置为一个函数memtotal,这样做的好处是能够提高代码的复用度,看起来也简介,后期修改直接改这个函数就可以了,不用全文修改。
下面是执行的结果
- [root@www tmp]# ./apache-mem.sh
- apache total process: 8
- apache total memsum:
- Shared_Clean: 5024 kB
- Pss: 3024 kB
- Size: 158368 kB
- Shared_Dirty: 20064 kB
- Swap: 0 kB
- Private_Dirty: 1216 kB
- Private_Clean: 0 kB
- Rss: 26304 kB
- delete tmp file!
时间有限,水平有限,这个脚本还有很多其他需要完善的地方,例如添加交互式的设计,统计哪个服务的内存由参数$1传递进去,脚本的健壮性还有待加强,算是抛砖引玉吧,请大家多交流。
最后想对shell刚入门的筒子说,只要你动手开始写shell就已经成功一半了,剩下的就是一个积累的过程。
加油!!!!你可以的!!!