目录
场景:需要对磁盘做如下信息统计
解决思路:由于只是临时统计因而怎么简单怎么来了,直接通过命令或拿网上的脚本修改一通进行统计。实际上操作起来才发现还有不少的疑问,因此便有了如下文章。
一. 统计磁盘使用情况
方式一: 通过 fdisk -l 命令统计服务器总磁盘大小
fdisk -l ,通过该命令将红框中对应的磁盘大小相加得出该服务器磁盘大小,查询结果如下图所示:
如上把红框中的磁盘进行求和得到该磁盘大小为:1288.5 + 214.7 + 598 = 2101.2 G
方式二:计算各分区磁盘空间真实使用情况
主要命令 df
[bigsoft@hdp56 ~]# df -PTh
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-LogVol00_root ext4 99G 57G 37G 62% /
tmpfs tmpfs 32G 72K 32G 1% /dev/shm
/dev/sda1 ext4 477M 42M 411M 10% /boot
/dev/mapper/VolGroup-LogVol01_data ext4 430G 354G 55G 87% /data
/dev/sdb1 ext4 197G 134G 54G 72% /data1
/dev/sdc1 ext4 1.2T 559G 563G 50% /data3
因为有十来台机器,因此通过脚本的方式将 df 命令中的信息统计出来;
脚本如下:
#!/bin/bash
file_dir="disk_info.tmp"
res_file="df_info.txt"
# 文件不存在则创建
if [ ! -f "$file_dir" ];then
touch '$filePath'
fi
if [ ! -f "$res_file" ];then
touch '$filePath'
fi
#计算只取第三列和第四列,即Size和Used
/bin/df -PTk |awk 'NR>1{print $3,$4}' > ${file_dir}
#计算磁盘total量
df_total=`cat ${file_dir}|awk -v t=0 '{t+=$1}END{print t}'`
#计算磁盘总使用量
df_used=`cat ${file_dir}|awk -v u=0 '{u+=$2}END{print u}'`
#计算总使用率
used_total=`echo "scale=4;${df_used}/${df_total}"|bc|awk -F'.' '{if($1==""){print 0.$0}else{print $0}}'`
VAR="eth0"
HOST_IP=$(ifconfig $VAR | grep "inet addr" | awk '{ print $2}' | awk -F: '{print $2}')
echo $HOST_IP > ${res_file};
echo -n "Total(G):" >> ${res_file}; echo "scale=0; $df_total/1024/1024"|bc >> ${res_file}
echo -n "Used(G):" >> ${res_file}; echo "scale=0; $df_used/1024/1024"|bc >> ${res_file}
echo -n "Avail(G):" >> ${res_file}; echo "scale=0; $df_total/1024/1024 - $df_used/1024/1024"|bc >> ${res_file}
echo -n "Use%:" >> ${res_file}; echo $used_total >> ${res_file}
注:使用scale 与 bc 进行计算,scale=2:计算的结果保留2位数
结果如下:
[bigsoft@hdp56 ~]# more df_info.txt
10.156.22.33
Total(G):1937
Used(G):1100
Avail(G):837
Use%:0.5679
方式一与方式二统计磁盘总大小的区别: 1288.5 + 214.7 + 598 - 1937 = 164.2G
为什么 df 与 fdisk 统计的结果有差距呢?
1. 需要明确的一点是 fdisk 显示的是该服务器中所挂载的磁盘,df -H 命令统计的是磁盘实际给用户使用的空间大小。
fdisk 是查看磁盘的信息, 对于一块磁盘,并不是整个空间都是给用户使用的,比如磁盘上会有主引导区,标记位,校验信息等。
这其实跟买手机一个样,手机商告诉你他家的手机存储为64G,但你仔细一看发现你能用的可能只有50G。
2. df 统计时并有加入Swap 所占用的Swap,对于Swap 可通过 free 命令进行查看。
3. 还有一种可能是fdisk 上有磁盘,但是并没有载到文件系统中(本文的磁盘都已挂载上了,如不知道怎么挂载可参考笔者这篇博文 Linux 磁盘挂载)
4. 硬盘厂家用的是十进制计算硬盘,以及分区会损失一定的存储空间。
结论:
1. 可以取方式一中计算出的磁盘大小结合方式二中计算实际使用的来进行统计。
2. 如果确定该服务器中所有磁盘都已经载到服务器上,并且对统计的是磁盘实际可用以及实际可用情况,可以直接运用方式二中计算出的所有值。
Linux磁盘管理常用三个命令为df、du和fdisk。
二. df 命令
功能:检查文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。
语法:
df [-ahikHTm] [目录或文件名]
常用命令参数:
-a:显示所有文件系统的磁盘使用情况,包括0块(block)的文件系统,如/proc文件系统。
-k:以k字节为单位显示。
-i:显示i节点信息,而不是磁盘块。
-t:显示各指定类型的文件系统的磁盘空间使用情况。
-x:列出不是某一指定类型文件系统的磁盘空间使用情况(与t选项相反)。
-T:显示文件系统类型。
-P: 显示POSIX 格式输出
简单样例如下:
样例一:将 /etc 底下的可用的磁盘容量以易读的容量格式显示
[root@www ~]# df -h /etc
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 9.5G 3.7G 5.4G 41% /
样例二:显示文件系统实际使用情况
[bigsoft@hdp56 ~]# df -PTh
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-LogVol00_root ext4 99G 57G 37G 62% /
tmpfs tmpfs 32G 72K 32G 1% /dev/shm
/dev/sda1 ext4 477M 42M 411M 10% /boot
/dev/mapper/VolGroup-LogVol01_data ext4 430G 354G 55G 87% /data
/dev/sdb1 ext4 197G 134G 54G 72% /data1
/dev/sdc1 ext4 1.2T 559G 563G 50% /data3
样例二解说:
Filesystem 文件系统的名称,一般为硬盘上的分区;
Type:文件系统类型。
Mounted on:文件系统挂载点。
如果你稍微注意会发现:Used + Avail < Size, 这是为什么呢?
原因:因为默认的每个分区都留了少量空间供系统管理员使用的缘故。
即使遇到普通用户空间已满的情况,管理员仍能登录和留有解决问题所需的工作空间。
清单中Use%列表示普通用户空间使用的百分比,若这一数字达到100%,分区仍然留有系统管理员使用的空间。
三、du 命令
英文原义为“disk usage”,统计目录(或文件)所占磁盘空间的大小。
功能:逐级进入指定目录的每一个子目录并显示该目录占用文件系统数据块(1024字节)的情况。若没有给出指定目录,则对当前目录进行统计。
语法:
du [-ahskm] 文件或目录名称
du 命令的各个选项含义如下:
-s:对每个Names参数只给出占用的数据块总数。
-a:递归地显示指定目录中各文件及子目录中各文件占用的数据块数。若既不指定-s,也不指定-a,则只显示Names中的每一个目录及其中的各子目录所占的磁盘块数。
-b:以字节为单位列出磁盘空间使用情况(系统默认以k字节为单位)。
-k:以1024字节为单位列出磁盘空间使用情况。
-c:最后再加上一个总计(系统默认设置)。
-l:计算所有的文件大小,对硬链接文件,则计算多次。
-x:跳过在不同文件系统上的目录不予统计。
实例:检查根目录底下每个目录所占用的容量
[root@www ~]# du -sm /*
7 /bin
6 /boot
.....中间省略....
0 /proc
.....中间省略....
1 /tmp
3859 /usr <==系统初期最大就是他了啦!
77 /var
四、fdisk
功能: Linux 的磁盘分区表操作工具。
语法:
fdisk [-l] 装置名称
选项与参数:
- -l :输出后面接的装置所有的分区内容。若仅有 fdisk -l 时, 则系统将会把整个系统内能够搜寻到的装置的分区均列出来。
fdisk -l 可列出所有的分区,包括没有挂上的分区,一般用这个命令来查找需要挂载的分区的位置。
如上图:可知该服务器总共有三个盘,分别是/dev/sda、/dev/sdb、 /dev/sdc 。由图可知/dev/sdc 没有正确的分区数据,因此其并没有挂载到文件系统中,也就是说目前该盘并不可用,用df 在系统中是看不到该盘的。
你可能会好奇:Disk /dev/mapper/VolGroup-LogVol00_root: 107.4 GB, 这个不算磁盘么?
以这个磁盘来做简单分析:
Disk /dev/sda: 598.0 GB, 597998698496 bytes
255 heads, 63 sectors/track, 72702 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x0005e352
这个硬盘是598G的,有255个磁面;63个扇区;72702个磁柱;
每个 cylinder(磁柱)的容量是 8225280 bytes=8225.280 K(约为)=8.225280M(约为);
分区序列 引导 开始 终止 容量 分区类型ID 分区类型
Device Boot Start End Blocks Id System
/dev/sda1 * 1 64 512000 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2 64 2675 20971520 82 Linux swap / Solaris
/dev/sda3 2675 72703 562498560 8e Linux LVM
说明:
硬盘分区的表示:在Linux 是通过hd*x 或 sd*x 表示的,其中 * 表示的是a、b、c ... ,x表示的数字 1、2、3 ... hd大多是IDE硬盘;sd大多是SCSI或移动存储;
引导(Boot):表示引导分区,在上面的例子中 hda1 是引导分区;
Start (开始):表示的一个分区从X cylinder(磁柱)开始;
End (结束):表示一个分区到 Y cylinder(磁柱)结束;
Id 和 System 表示的是一个意思,id看起来不太直观,我们要在fdisk 一个分区时,通过指定id来确认分区类型;比如 7表示的就NTFS 分区;这个在fdisk 中要通过 t 功能来指定。
Blocks(容量):单位是K;一个分区容量的值 Blocks = (相应分区End数值 - 相应分区Start数值)x 单位cylinder(磁柱)的容量。
注:换算单位以硬盘厂家提供的10进位算起,如果以操作系统二进制来算,这个分区容量应该更少一些,得出的这个值和我们通过 fdisk -l 看到的 /dev/hda1的值是大体相当的,因为换算方法不一样,所以也不可能尽可能的精确;
再加上分区时的一点损失之类,有时或大或小是存在的;我们查看分区大小或者文件的时候,还是用十进制来计算比较直观;推算办法是 byte 向前推小数点三位就是K ,K单位的值向前推小数点三位就是M,M向前推小数点三位就是G。
如何估算上述硬盘是否都被划分了呢
1. 查看硬盘分区数据是否存在,如下图没有存在分区,则说明该盘还没正式可供用户使用,故可进行分区;
2. 看磁盘一共有多少个磁柱,如下所示将上图的 /dev/sdc 进行分区后如下所示:
Disk /dev/sdc: 1288.5 GB, 1288490188800 bytes
255 heads, 63 sectors/track, 156650 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x2a47c305
Device Boot Start End Blocks Id System
/dev/sdc1 1 156650 1258291093+ 83 Linux
该盘一共有磁柱:156650 cylinders
而该盘下的分区 /dev/sdc1 ,Start - End 是从 1到156650 ,可见其占用了所有的磁柱,故该盘已经没有空间可再进行分区了。
当然你也可以通过目前 磁盘下所有的分区(Blocks)求和大概看出还有多少空间可进行分区。
总的来说一般从磁柱上进行判断是最方便的,比如Start与End 之间有断层那么说明还可进行分区。
比如说 /dev/sdc 下有两个分区,a分区 Start - End : 1 - 100,b分区 Start - End : 5001 - 156650, 这样很明显 a 的End 与 b 的Start 之间还有 101 - 5000,也就是说这101 - 5000还可以再进行分区。
参考文档: