首先我是一个刚转正进入公司的小白,各位大佬请尽管说我菜,因为写这个脚本看似不难,实则花了我这个小白菜好多时间。刚出差到一个城市,我就被一个老同事叫练写个客户需要的脚本,来获取系统磁盘的总磁盘空间大小情况了。 刚接到这个任务的我,肯定鼓足了干劲了,心里想这不简单嘛,百度一下就有结果了,再修改下脚本,交差!心里想的好,可真正实施起来也挺难的。 刚开始我就在想如何获取总磁盘空间的大小呢?是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=$((1000d_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=$((1000d_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_u1000] #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_u1000] #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,之前没有认真看过,测试多台主机后才发现了问题。 脚本测试结果如下: 看着还是挺顺利的,可以拿去给老同事交差了。