生成 df 命令总计特定文件系统
producing df command a grand total specific filesystem
只需要做一些我可以自己管理的基本事情,但结果我对我得到的结果有疑问...
我需要在两个不同服务器上的特定文件系统上使用 df 命令生成总计。
ssh server1 df -mP | egrep "/dev/md10|/dev/md11" | sort ; ssh server1 df -mP --total | grep "total" | egrep -v "/dev/md10|/dev/md11
结果:
/dev/md10 183004016 87303581 95700436 48% /si001c1
/dev/md11 183004016 165986430 17017587 91% /si001c2
total 366565396 253332843 113232554 70%
然后我在第二台服务器上使用相同的命令来获取总计。我的问题是,我得到的总计似乎不正确(我不确定),以及如何通过使用单行命令或作为 bash 中的基本脚本使用相同的命令组合两者来生成总计。感谢您的帮助。
更新:
这是遵循@EdmCoff 的指南后的更新。
printf "Grand total: " ; (ssh server1 df -m /dev/md11 ; ssh server2 df -m /dev/md1*) | awk 'a+=;b+=;c+=;d+=/3} END {print a" "b" "c" "d%}'
结果:
Grand total: 549012050 501832399 47179652 92%
构建脚本(重新完成):
#!/bin/bash
(ssh server1 df -m --no-sync "/dev/md11" ; ssh server2 df -m --no-sync "/dev/md1*") | sed -e /^Filesystem/d | sort > df_udsall
#(cat df_udsall)
printf "\nUDS:\nserver1 & server2\n"
printf "Mounted on Free space Disk usage Use"%%" Disk state"
while read df_udsall
do
USAGE=$(echo $df_udsall ; echo $grand_total) | awk '{print }' | cut -d"%" -f1
if [[ "$USAGE" -ge " 95" ]]
then
STATUS='CRITICAL'
elif [[ "$USAGE" -ge " 90" ]]
then
STATUS='WARNING'
else
STATUS='OK'
fi
printf "$(echo $df_udsall | awk '{print , , , }' > df_udsall_stats)"
column -t df_udsall_stats | perl -ne 'chomp ; printf "\n%-18s %8s %12s %6s %-2s", split / +/' ; printf "`echo -ne $STATUS`"
done < df_udsall
printf "\n\nGrand total " ; cat df_udsall | awk '{b+=;c+=;d+=/3} END {print b" "c" "d "%"}' > grand_total
column -t grand_total | perl -ne 'chomp ; printf "%15s %12s %6s %-2s", split / +/' ; printf "`echo -ne $STATUS`"
rm -f df_udsall df_udsall_stats grand_total
上面的脚本需要一些微调。
预期结果:
UDS:
server1 & server2
Mounted on Free space Disk usage Use% Disk state
/sic1 16202762 166801255 92% WARNING
/sic2 15648157 167355860 92% WARNING
/sic3 15256569 167747448 92% WARNING
Grand total: 47107488 501904563 92% OK
修复了 tripleee 脚本输出结果:
UDS:
server1 & server2
Mounted on Free space Disk usage Use% Disk state
/sic001c1 92146461 90857556 50% OK
/sic001c2 16873531 166130486 91% WARNING
/sic001c3 16832710 166171307 91% WARNING
/sic001c4 16362388 166641629 92% WARNING
Grand total: 142215090 589800978 81 OK%
这里尝试将您的脚本重构为 Awk 完全控制输出的计算和格式的版本,如几条评论中所建议的那样。我已经内嵌了您可能想要删除的评论。
#!/bin/bash
# use a loop to reduce duplication of ssh options etc
while read -r server mounts; do
ssh "$server" df -m --no-sync $mounts </dev/null
done <<\____SERVER__MOUNTS |
server1 /dev/md10 /dev/md11
server2 /dev/md12 /dev/md13
____SERVER__MOUNTS
# sed -e /^Filesystem/d inlined into Awk below
sort |
# pipe into awk
awk 'BEGIN { print "UDS:\nserver1 & server2"
# Maybe use printf here too
print "Mounted on Free space Disk usage Use% Disk state"
fmt="%-18s %8i %12i %6s %-2s"
}
function status(num) {
# Awk conveniently ignores any trailing string
# so you can compare 95% to 95 numerically
if (num > 95) result="CRITICAL"
else if (num > 90) result="WARNING"
else result="OK"
return(result)
}
! /^Filesystem/ {
printf fmt "\n", , , , , status()
# EdmCoff''s hack, too lazy to change to legible variable names
# adapted to defer division until we know the final value of n
a+=;b+=;c+=;dd+=;n++
}
END { d=dd/n;
printf "\n" fmt "%%\n",
"Grand total:", c, b, int(d), status(d) }'
我显然没有办法用真实的输入来测试它,所以可能存在一些小的格式错误等。我希望我掌握了足够多的逻辑,至少可以向你展示如何将这个处理的主体实现为一个 Awk脚本。
请注意没有任何临时文件(如果它被中断,您的原始脚本将无法清理这些文件;use trap
)并且使用缩进来帮助您查看循环和条件。
只需要做一些我可以自己管理的基本事情,但结果我对我得到的结果有疑问...
我需要在两个不同服务器上的特定文件系统上使用 df 命令生成总计。
ssh server1 df -mP | egrep "/dev/md10|/dev/md11" | sort ; ssh server1 df -mP --total | grep "total" | egrep -v "/dev/md10|/dev/md11
结果:
/dev/md10 183004016 87303581 95700436 48% /si001c1
/dev/md11 183004016 165986430 17017587 91% /si001c2
total 366565396 253332843 113232554 70%
然后我在第二台服务器上使用相同的命令来获取总计。我的问题是,我得到的总计似乎不正确(我不确定),以及如何通过使用单行命令或作为 bash 中的基本脚本使用相同的命令组合两者来生成总计。感谢您的帮助。
更新: 这是遵循@EdmCoff 的指南后的更新。
printf "Grand total: " ; (ssh server1 df -m /dev/md11 ; ssh server2 df -m /dev/md1*) | awk 'a+=;b+=;c+=;d+=/3} END {print a" "b" "c" "d%}'
结果:
Grand total: 549012050 501832399 47179652 92%
构建脚本(重新完成):
#!/bin/bash
(ssh server1 df -m --no-sync "/dev/md11" ; ssh server2 df -m --no-sync "/dev/md1*") | sed -e /^Filesystem/d | sort > df_udsall
#(cat df_udsall)
printf "\nUDS:\nserver1 & server2\n"
printf "Mounted on Free space Disk usage Use"%%" Disk state"
while read df_udsall
do
USAGE=$(echo $df_udsall ; echo $grand_total) | awk '{print }' | cut -d"%" -f1
if [[ "$USAGE" -ge " 95" ]]
then
STATUS='CRITICAL'
elif [[ "$USAGE" -ge " 90" ]]
then
STATUS='WARNING'
else
STATUS='OK'
fi
printf "$(echo $df_udsall | awk '{print , , , }' > df_udsall_stats)"
column -t df_udsall_stats | perl -ne 'chomp ; printf "\n%-18s %8s %12s %6s %-2s", split / +/' ; printf "`echo -ne $STATUS`"
done < df_udsall
printf "\n\nGrand total " ; cat df_udsall | awk '{b+=;c+=;d+=/3} END {print b" "c" "d "%"}' > grand_total
column -t grand_total | perl -ne 'chomp ; printf "%15s %12s %6s %-2s", split / +/' ; printf "`echo -ne $STATUS`"
rm -f df_udsall df_udsall_stats grand_total
上面的脚本需要一些微调。
预期结果:
UDS:
server1 & server2
Mounted on Free space Disk usage Use% Disk state
/sic1 16202762 166801255 92% WARNING
/sic2 15648157 167355860 92% WARNING
/sic3 15256569 167747448 92% WARNING
Grand total: 47107488 501904563 92% OK
修复了 tripleee 脚本输出结果:
UDS:
server1 & server2
Mounted on Free space Disk usage Use% Disk state
/sic001c1 92146461 90857556 50% OK
/sic001c2 16873531 166130486 91% WARNING
/sic001c3 16832710 166171307 91% WARNING
/sic001c4 16362388 166641629 92% WARNING
Grand total: 142215090 589800978 81 OK%
这里尝试将您的脚本重构为 Awk 完全控制输出的计算和格式的版本,如几条评论中所建议的那样。我已经内嵌了您可能想要删除的评论。
#!/bin/bash
# use a loop to reduce duplication of ssh options etc
while read -r server mounts; do
ssh "$server" df -m --no-sync $mounts </dev/null
done <<\____SERVER__MOUNTS |
server1 /dev/md10 /dev/md11
server2 /dev/md12 /dev/md13
____SERVER__MOUNTS
# sed -e /^Filesystem/d inlined into Awk below
sort |
# pipe into awk
awk 'BEGIN { print "UDS:\nserver1 & server2"
# Maybe use printf here too
print "Mounted on Free space Disk usage Use% Disk state"
fmt="%-18s %8i %12i %6s %-2s"
}
function status(num) {
# Awk conveniently ignores any trailing string
# so you can compare 95% to 95 numerically
if (num > 95) result="CRITICAL"
else if (num > 90) result="WARNING"
else result="OK"
return(result)
}
! /^Filesystem/ {
printf fmt "\n", , , , , status()
# EdmCoff''s hack, too lazy to change to legible variable names
# adapted to defer division until we know the final value of n
a+=;b+=;c+=;dd+=;n++
}
END { d=dd/n;
printf "\n" fmt "%%\n",
"Grand total:", c, b, int(d), status(d) }'
我显然没有办法用真实的输入来测试它,所以可能存在一些小的格式错误等。我希望我掌握了足够多的逻辑,至少可以向你展示如何将这个处理的主体实现为一个 Awk脚本。
请注意没有任何临时文件(如果它被中断,您的原始脚本将无法清理这些文件;use trap
)并且使用缩进来帮助您查看循环和条件。