多服务器统计用户存储总空间

文章目录

  • 脚本
    • check_disk.sh
    • count_disk_uasge_of_everyone.sh
  • 其他文件
    • user_list.txt
    • XXX_check_disk.txt
    • log.txt
    • disk_usage.txt
  • 部署
    • 公钥
    • 定时任务

背景:实验室有5台服务器。不同用户在多个服务器上都可以有账号,但是硬盘容量有限,如果一个人占用大量存储会导致其他人没得用。作为管理员,需要统计 每个用户在每一台服务器上占用的存储空间,然后计算占用的 总空间,并记录在一个文档中方便查看。服务器的ID来自其局域网IP地址的最后一部分,分别为 102、106、112、120、146
注意:一下所有操作均使用 root账户
整体流程

  1. 特定服务器(106服务器)制作密钥然后发给其他各个服务器;
  2. 所有服务器每天3点半运行check_disk.sh,将本地的所有用户的个人目录大小记录在XXX_check_disk.txt中,然后汇总到特定服务(106服务器)上;
  3. 特定服务器(106服务器)每天6点半运行count_disk_uasge_of_everyone.sh,根据user_list.txt统计每个用户在每台服务器上的个人目录大小然后求和,记录在disk_usage.txt
  4. 每台服务器都使用crontab添加定时任务

接下来介绍其中的细节,请阅读玩全文后再操作,如果有任何BUG欢迎留言:

脚本

check_disk.sh

这个文件需要部署到每一台服务器上,放在/root下。统计本地服务器上所有用户的存储空间,然后统一发送到一个特定服务器上(我这里选择的是106服务器)。脚本内容如下,

#!/bin/bash
#获取IP地址,用以识别服务器名称
ip_address=$(/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:")
#IP地址后三个数字为服务器代号
ID=${ip_address:0-3:3}
#文件名
file_name="$ID"_check_disk.txt
#添加时间和个人文件夹大小
echo `date +"%Y-%m-%d"` > $file_name
du -sm /home/* >> $file_name
if [ "$ID" != "106" ]
    then
        #统一发送到106服务器
        scp -i ~/.ssh/106_id_rsa $file_name [email protected]:/root/$file_name
    else 
        mv $file_name 106_check_disk.txt
fi

count_disk_uasge_of_everyone.sh

这个脚本用来统计用户在每台服务器上的存储空间和在所有服务器上的总存储空间。它只部署在特定服务器上,这里就是上面说的106服务器,放在/root下。

#!/bin/bash
date_now=$(date +"%Y-%m-%d")
##### 创建文件disk_usage.txt,存储每个人的文件占有情况 #####
declare -i num=$(wc -l user_list.txt | awk '{print $1}')
#表头,覆盖旧的内容
echo "******************************************************" > disk_usage.txt
echo "********************  $date_now  ********************" >> disk_usage.txt
echo "******************************************************" >> disk_usage.txt
echo -e "姓名\t102(M)\t106(M)\t112(M)\t120(M)\t146(M)\t总和\t单位" >> disk_usage.txt
for (( i=2;i<=$num;i=i+1 ))
    do
        #每个人的使用情况先用服务器ID代替,方便后面查找到后替换
        echo -e "$(sed -n "$i"p user_list.txt | awk '{print $1}')\t_102\t_106\t_112\t_120\t_146\tsum\tunit" >> disk_usage.txt
    done

##### 检索每台服务器上的 #####
#日志文件log.txt添加分割线
echo "********************  $date_now  ********************" >> log.txt
#统计每个服务器
for ID in 102 106 112 120 146
    do
    filename="$ID"_check_disk.txt
    #判断文件是否存在
    if [ ! -e "$filename" ]; then
        echo -e "$date_now \t $filename not exists." >> log.txt
        continue
    fi
    #判断文件时间是否一致
    if [ "$(grep -v "\home" "$filename")" != "$date_now" ]; then
        echo -e "$date_now \t $filename is old file." >> log.txt
        continue
    fi
    #获取文件行数,即用户数
    declare -i line_num=$(wc -l $filename | awk '{print $1}') #wc -l "$filename"输出行号和文件名
    #echo "line_num is $line_num" 

    #处理每个用户
    for (( i=2;i<=$line_num;i=i+1 ))
        do
        #单独获取用户名和其使用的存储容量
        username=$(sed -n "$i"p $filename | cut -f 3 -d "/" )
        disk_usage=$(sed -n "$i"p $filename | awk '{print $1}' )
        #echo "username is $username, disk_usage is $disk_usage"

        #判断该用户是否存在于user_list.txt中
        if [ "$(grep -w $username user_list.txt)" == "" ];then
            echo -e "$date_now \t $username in $ID not exits in user_list.txt." >> log.txt
            continue
        fi

        #获取该用户的中文名       
        fullname=$(grep -w $username user_list.txt | awk '{print $1}') #注意:需要全匹配!!!
        #echo "fullname is $fullname"

        #获取该用户在disk_usage.txt中的第几行
        user_location=$(grep -n -w "$fullname" disk_usage.txt | cut -f 1 -d ':')
        #echo "user_location is $user_location"

        #将该用户的存储容量写入disk_usage.txt的对应位置中
        sed -i "$user_location s/_$ID/$disk_usage/g" disk_usage.txt
        done

    done

##### 因为有些用户在有些服务器上没有账号,所以要将disk_usage.txt中没有统计过的地方(即为“_102”之类的地方)替换为0 #####
for ID in 102 106 111 112 120 146
    do
    sed -i "s/_$ID/0/g" disk_usage.txt
    done
declare -i user_num=$(wc -l disk_usage.txt | awk '{print $1}')

##### 计算每个用户的存储空间总使用量 #####
declare -i user_num=$(wc -l disk_usage.txt | awk '{print $1}')
for (( i=5;i<=$user_num;i++ )) #前四行驶表头
    do
    #计算总量
    declare -i usage_102=$(sed -n "$i"p disk_usage.txt | awk '{print $2}' )
    declare -i usage_106=$(sed -n "$i"p disk_usage.txt | awk '{print $3}' )
    declare -i usage_112=$(sed -n "$i"p disk_usage.txt | awk '{print $4}' )
    declare -i usage_120=$(sed -n "$i"p disk_usage.txt | awk '{print $5}' )
    declare -i usage_146=$(sed -n "$i"p disk_usage.txt | awk '{print $6}' )
    declare -i summary=$usage_102+$usage_106+$usage_112+$usage_120+$usage_146 #实验证明也可以不加“$”
    
    #人性化显示
    if [ $summary -gt 1024 ] #-gt表示大于
        then
        summary=summary/1024
        unit=G
    else
        unit=M
    fi

    #echo "this is $usage_102 $usage_106 $usage_112 $usage_120 $usage_146 $summary"
    
    #填入disk_usage.txt
    sed -i "$i s/sum/$summary/g" disk_usage.txt
    sed -i "$i s/unit/$unit/g" disk_usage.txt
    done

其他文件

user_list.txt

这个文件需手动准备,记录了所有用户的名字、在不同服务器上的用户名和联系方法,放在特定服务器(即106服务器)。我是让所有在服务器上有账号的人填写表格,示例如下:

姓名 102上账号 106上账号 112上账号 120上账号 146上账号 手机 邮箱
小明 xm xm xm xiaoming 10086 [email protected]
小红 xh xiaohong xiaohong xh 10086 [email protected]
小军 xiaojun xiaojun 10086 [email protected]

我使用window的excel统计表格的,然后把内容直接粘贴到user_list.txt,再把user_list.txt复制到106服务器上的/root下面
注意:姓名不能重复,否则回报如下错误

sed: -e expression #1, char 3: unknown command: `
'

XXX_check_disk.txt

check_disk.sh自动生成,位于每个服务器的/root路径下。记录本地服务上每个用户的个人文件夹的大小(以M为单位),例如:

2020-02-27
312	/home/xm
31	/home/xh
40	/home/xiaojun

每次运行check_disk.sh都会覆盖旧的XXX_check_disk.txt

log.txt

count_disk_uasge_of_everyone.sh自动生成,位于特定服务器(106服务器)的/root路径下。记录了count_disk_uasge_of_everyone.sh运行时的错误日志,内容有:

  1. 日期
  2. 找不到XXX_check_disk.txt
  3. XXX_check_disk.txt里记录的时间跟现在的对不上,即没有收到新版本
  4. XXX_check_disk.txt中的用户不存在于user_list.txt

每次运行产生的错误日志都会追加到log.txt

disk_usage.txt

count_disk_uasge_of_everyone.sh自动生成,位于特定服务器(106服务器)的/root路径下。记录了每个用户在每台服务上占用存储空间和它们的总和,如下:

******************************************************
********************  2020-02-27  ********************
******************************************************
姓名	102	106	112	120	146	总和
小明	312	0	0	0	33	345M
小红	31	9	0	500	500	1G
小军	40	0	22	0	0	62M

每次运行count_disk_uasge_of_everyone.sh都会覆盖旧的disk_usage.txt

部署

公钥

为了使用scp传输文件时可以免密,这里使用密钥连接方式(其他的我搞不定)。在特定服务器(106服务器)上,执行命令ssh-keygen,选择路径和输入密码时都按回车直接跳过,然后执行

cat id_rsa.pub >> authorized_keys
#赋予文件权限
chmod 600 authorized_keys
chmod 700 ~/.ssh
cp id_rsa 106_id_rsa

然后把106_id_rsa放到其他每个服务器的/root/.ssh下面

定时任务

执行命令crontab -e,第一次运行的时候会让选择编辑器,如下
多服务器统计用户存储总空间_第1张图片
每个服务器都要在其中添加如下命令,让check_disk.sh每天3点半运行一次:
多服务器统计用户存储总空间_第2张图片
特定服务器(106服务器)上还要再加上如下内容,让count_disk_uasge_of_everyone.sh每天6点半运行一次

#每天统计每个用户在所有服务器上占用空间之和
30 6 * * * /root/count_disk_uasge_of_everyone.sh

具体格式参考附录博客。

Linux crontab 命令

你可能感兴趣的:(多服务器统计用户存储总空间)