首先我是一个刚转正进入公司的小白,各位大佬请尽管说我菜,因为写这个脚本看似不难,实则花了我这个小白菜好多时间。刚出差到一个城市,我就被一个老同事叫练写个客户需要的脚本,来获取系统磁盘的总磁盘空间大小情况了。
刚接到这个任务的我,肯定鼓足了干劲了,心里想这不简单嘛,百度一下就有结果了,再修改下脚本,交差!心里想的好,可真正实施起来也挺难的。
刚开始我就在想如何获取总磁盘空间的大小呢?是df -h命令,把Size里所有的空间都相加?但是里面有挂载的一些目录也算进来,肯定不对。或者直接算/目录下的总大小?看似就是这样,但实际上是没有算进外挂的硬盘,也不对的。我就去百度。
结果我百度了很久,也不知道具体是怎么算出所有磁盘的空间大小,我也是一边工作一边想的,也问了些其他同事,过程怎样就不说了,反正最后就确定了用fdisk -l算总值计算总磁盘空间,因为fdisk命令可以看到其他挂载的硬盘信息和分区信息。用df 来算总的已使用空间大小,因为这里实在是显示了所有磁盘使用的信息。
fdisk -l的命令结果如下图:
我就是要算方框中的磁盘总和大小,来代表磁盘总空间的大小。这个想法原本我也以为是错的,但是目前不知道用什么办法来代替磁盘总空间了。但是不管了,就是想先用shell脚本的三剑客--awk, grep, sed来取命令中的字符内容了。
在这里我使用了grep -n ‘ 内容’ 的参数,用来过滤信息字符中带有’内容’字符的行,用awk $n 来打印每行中的第几个参数,也用awk来计算字节的总和。原本想用单位转换的计算来算总和的,但还是觉得尽量简单点好。
于是初始的shell脚本经过多次测试,和人工计算核对数据以后有了个雏形:
#!/bin/bash
d_t=$(fdisk -l | grep -n '磁盘' |grep -n '字节'|awk '{print $4}'|awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
#磁盘总空间
echo -e "${d_t}"
#磁盘已使用总空间
d_u=$(df | awk '{print $3}'| grep -v 已用| awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
echo -e "${d_u}"
#磁盘总剩余空间
d_f=$[${d_t}-${d_u}]
这是一个主要的核心算法。这个是慢慢看以前学的shell脚本基础,慢慢推算出来的。其中awk 'BEGIN{sum=0}{sum+=$1}END{print sum}'是计算一组数字的总和,相信网友以后会用到。
然后,跑去跟老同事说,大概的思路想法出来了,看看还有没有下一个需求,然后他验了下。提出说要加个判断,输入什么值就有什么结果,还有尽量满足中英文的linux系统。
我想了下,这种不就是case和if,then吗?以前学过的,然后又完善了脚本,如下:
#!/bin/bash
#磁盘总空间大小,字节单位
disk_total() {
d_t=$(fdisk -l | grep -n '磁盘' |grep -n '字节'|awk '{print $4}'|awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
if [ ${d_t} -eq 0 ];then
d_t2=$(fdisk -l | grep -n 'Disk' |grep -n 'bytes'|awk '{print $5}'|awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
echo -e "${d_t2}"
#echo -e "磁盘总空间大小为:${d_t2}B"
else
echo -e "${d_t}"
#echo -e "磁盘总空间大小为:${d_t}B"
fi
}
#磁盘总使用大小,注意单位是1k
disk_used() {
d_uk=$(df | awk '{print $3}'| grep -v 已用| awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
d_u=$((1000*d_uk))
if [ ${d_u} -eq 0 ];then
d_u2k=$(df | awk '{print $3}'| grep -v Used| awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
d_u2=$((1000*d_u2k))
echo -e "${d_u2}"
else
echo -e "${d_u}"
fi
}
#剩余总空间计算
disk_free() {
d_t=$(fdisk -l | grep -n '磁盘' |grep -n '字节'|awk '{print $4}'|awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
d_u=$(df | awk '{print $3}'| grep -v 已用| awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
d_f=$[${d_t}-d_u*1000]
#d_f="expr $d_t-$d_u"
#echo "$d_u"
#echo "${d_u}"
if [ ${d_t} -eq 0 ];then
d_t2=$(fdisk -l | grep -n 'Disk' |grep -n 'bytes'|awk '{print $5}'|awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
d_u2=$(df | awk '{print $3}'| grep -v Used| awk 'BEGIN{sum=0}{sum+=$1}END{print sum}')
d_f2=$[${d_t2}-d_u*1000]
#d_f2=`expr $d_t2-$d_u2`
echo -e "${d_f2}"
else
echo -e "${d_f}"
fi
}
case "$1" in
dt)
disk_total
;;
df)
disk_free
;;
du)
disk_used
;;
*)
echo "Usage: $0 {dt=disk_total}{df=disk_free}{du=disk_used}"
;;
esac
这个脚本也是测试完善了很多次才渐渐发现了些问题的,例如:输入df 命令时,那个used的单位不是字节了,而是kB,之前没有认真看过,测试多台主机后才发现了问题。
脚本测试结果如下:
看着还是挺顺利的,可以拿去给老同事交差了。
技术交流欢迎加入Q群:177428068