分析df和du的区别

  Linux、Unix-Like平台的用户都可能会发现,du与df的查询结果会不一致。最常见的情况就是,df显示的已使用磁盘占用率比du统计出来的结果要大很多。

  下面说下两者结果不同的原因,主要是由于两者计算结果的方式不同。

  先来看看两者是如何计算的

  df命令:

  df是从文件系统考虑,通过文件系统中未分配的空间来确定文件系统中已分配空间的大小。例如:如果一个文件系统中有8192个512-byte 块,并且4096个块没有被分配出去,那么已分配的空间就是4096个512-byte 的块。

  已分配空间=空间总数-未分配空间

  df中的used还包含了程序申请的、被程序占用的空间等等。因为基于文件系统总体来计算,所以df命令是报告文件系统空间使用情况最可靠的命令。

  du命令

  du是面向文件的命令,它计算分配给指定文件或者目录的空间。du命令必须跟着目的参数,而且不能隔离文件系统。

  例如:运行 #du /命令将计算所有在/文件系统下所有文件的空间分配信息。其中包括/文件系统所有的文件和安装在/下面的,例如/tmp, /var和/usr下面的其他文件系统的文件。可以用du命令带-x参数来限制仅在文件系统内进行操作。但是有时候会导致输出结果不完全。

  du命令只计算被文件占用的空间。不计算文件系统metadata 占用的空间,如inodes, inode maps, 或者disk maps。

  du命令只计算那些可以访问的文件所占用的存储空间。

  下面两种情况du命令不会计算已经分配给文件的空间。

  Case1:

  文件被隐藏了。

  例如:如果一个文件存放在/bobby 目录下, 接着有文件系统安装(mount)在/bobby目录下, 那么du 命令将不会计算 /bobby 目录下的文件所占用的存储空间。

  Case2:

  文件被其他的应用的打开了,接着文件被删除了(rm命令删除)。 在这种情况下,文件所占用的存储空间将维持着被分配的状态直到所有对这个文件的访问都被关闭。由于目录中没有这个文件的相关纪录,du命令将不会计算这个文件的被分配空间,但df命令将计算这部分已分配的空间。

  除rm外,有些不明显的操作也会产生类似的问题。

  例如gzip命令,其对某个文件xxx.log进行压缩时,会产生一个新的xxx.log.gz文件,完成后,会把原来的xxx.log删除。这时,若仍有进程在使用xxx.log文件。那么,实际上该文件还是只会标记为deleted,其空间也不会释放,问题与上面提到的情况是相同的。所以,在编写脚本时,可先判断是否仍有进程正在使用该文件,然后再进行gzip操作。

  通俗点讲,du就是遍历某个目录,把所有文件的大小加起来,都是那看得见的东西的和

  简单的模拟测试实验(以下实验属引用,未测试。看了下输出,结果应该没问题。呵呵!)

  实验情况

  1、创建并删除文件

  创建文件前的磁盘容量情况:

? View Code BASH
1
2
3
4
# df -h
文件系统              容量  已用 可用 已用% 挂载点
/dev/sda1              12G  5.7G  5.5G  51% /
tmpfs                 506M     0  506M   0% /dev/shm

  创建文件:

? View Code BASH
1
2
3
4
# dd if=/dev/zero of=test.iso bs=1024k count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 14.3055 seconds, 73.3 MB/s

  现在的磁盘情况:

? View Code BASH
1
2
3
4
# df -h
文件系统              容量  已用 可用 已用% 挂载点
/dev/sda1              12G  6.7G  4.6G  60% /
tmpfs                 506M     0  506M   0% /dev/shm

  模拟某个进程正在使用该文件:

? View Code BASH
1
# tail -f /tmp/test.iso

无觅相关文章插件,快速提升流量

  2、删除该文件

  打开另一个终端,登陆到系统中。查看是否有进程正在使用上面创建的文件:

? View Code BASH
1
2
# lsof |grep test.iso
tail      2175      root    3r      REG        8,1 1048576000     752972 /tmp/test.iso

  把该文件删掉,并确认:

? View Code BASH
1
2
3
4
# rm /tmp/test.iso
rm:是否删除 一般文件 “/tmp/test.iso”? y
# ls /tmp/test.iso
ls: /tmp/test.iso: 没有那个文件或目录

  查看是否还有进程在使用(注意结尾的标记):

? View Code BASH
1
2
# lsof |grep test.iso
tail      2175      root    3r      REG        8,1 1048576000     752972 /tmp/test.iso (deleted)

  查看磁盘使用情况:

? View Code BASH
1
2
3
4
5
6
7
# df -h
文件系统              容量  已用 可用 已用% 挂载点
/dev/sda1              12G  6.7G  4.6G  60% /
tmpfs                 506M     0  506M   0% /dev/shm
 
# cat /proc/diskstats |grep sda1
   8    1 sda1 54385 5184 1626626 130090 20434 635997 5251448 5345733 0 111685 5475829

  可见,虽然从ls已经无法找到该文件,但因为tail进程仍在使用该文件,故实际上内核并没有把这文件所占用的空间释放出来(df的结果)。

  3、停止相关进程

  回到第一终端,用Ctrl+C 终止tail 进程,查看结果:

? View Code BASH
1
2
3
4
5
6
7
# df -h
文件系统              容量  已用 可用 已用% 挂载点
/dev/sda1              12G  5.7G  5.5G  51% /
tmpfs                 506M     0  506M   0% /dev/shm
 
# cat /proc/diskstats |grep sda1
   8    1 sda1 54473 5184 1627402 130617 20453 636042 5251960 5345756 0 112226 5476379

  至此,文件所占用的空间已完全释放。

  从上面的实验,可得出一些情况:

  1、若有进程在占用某个文件,而其他进程把这文件删掉,只会删除其在磁盘中的标记,而不会释放其占用的磁盘空间;直到所有访问该文件的进程退出为止;
  2、df是从内核中获取磁盘占用情况数据的,而du是统计当前磁盘文件大小的结果,由于磁盘标记已被删掉,因此du 不会计算上述被删除文件的空间,导致df 与 du的结果不一致。

  解决问题

  通常的解决方法有两个

  1、把占用文件的相关进程关闭

  这可通过下面的命令得到这些已被删除,但未释放空间的文件和进程信息:

? View Code BASH
1
# lsof |grep deleted

  找到这些进程后,在安全的情况下把其关闭,空间自会马上释放。

  2、以清空的方式替代删除

  归根到底,产生问题的原因是,访问该文件的文件指针(句柄),在rm动作后,因为进程仍在访问,因此,仍处在文件里面(中间或结尾处)。所以,如果用清空的方式,把文件指针重置,该文件所占用的空间也会马上释放出来。

? View Code BASH
1
2
3
4
5
6
7
8
9
# echo > /tmp/test.iso
 
# df -h
文件系统              容量  已用 可用 已用% 挂载点
/dev/sda1              12G  5.7G  5.5G  51% /
tmpfs                 506M     0  506M   0% /dev/shm
 
# tail -f /tmp/test.iso
tail: /tmp/test.iso: file truncated

  所以,对于常发生类似问题的文件,如:日志记录文件等。以改名、清空、删除的顺序操作可避免问题。

  参考文档

  http://www.linuxfly.org/post/575/
  http://hi.baidu.com/ioah/blog/item/5792bc4c8d9cc0f2d62afc6e.html

转载自:http://www.mike.org.cn/articles/analysis-of-the-difference-df-and-du/

### Linux `du` 命令与 `df` 命令的区别及使用方法 #### 一、命令功能概述 - **`du` 命令**主要用于统计指定目录或文件的磁盘使用情况,能够显示单个文件或者整个目录树所占用的空间大小[^1]。 - **`df` 命令**则用于查看文件系统的整体磁盘空间使用状况,包括已用空间、可用空间以及挂载点等信息[^4]。 --- #### 二、具体区别 | 特性 | `du` 命令 | `df` 命令 | |---------------------|-----------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------| | **主要用途** | 统计特定目录或文件的磁盘使用量 | 查看整个文件系统的磁盘空间使用情况 | | **操作对象** | 单个文件或目录 | 文件系统 | | **输出内容** | 展示每个子目录及其父目录的磁盘占用情况 | 提供文件系统的总量、已用量、剩余量挂载位置 | | **单位支持** | 支持多种单位(默认为字节),可通过参数调整 | 默认以 KB 或其他指定单位展示 | --- #### 三、常见选项与用法 ##### 1. `du` 命令常用选项 - `-h, --human-readable`: 使用人类可读的形式表示文件大小 (如 K、M、G)[^5]。 - `-s, --summarize`: 只显示总计值而列出每个子项。 - `-a, --all`: 列出所有文件目录的信息。 - `-c, --total`: 在最后加上总计数。 - `-i`: 显示 inode 的使用情况而非实际数据块[^3]。 ###### 示例代码 ```bash # 显示当前目录下的总大小 du -sh . # 显示当前目录下每个文件夹的具体大小 du -h --max-depth=1 . ``` ##### 2. `df` 命令常用选项 - `-h, --human-readable`: 类似于 `du` 的 `-h` 参数,使输出更易理解。 - `-T`: 显示文件系统类型。 - `-k`: 以千字节(KB)为单位报告磁盘空间。 - `-t type`: 仅显示某种类型的文件系统。 - `-x type`: 排除某些类型的文件系统。 ###### 示例代码 ```bash # 查看所有挂载点的磁盘使用情况 df -h # 同时显示文件系统类型 df -Th ``` --- #### 四、注意事项 - 如果需要分析某个目录内部结构并找出大文件,则应优先考虑使用 `du` 命令。 - 对于监控服务器的整体存储状态而言,`df` 更加适合因为可以快速获取全局视角的数据。 - 当涉及特殊需求比如只关心 iNode 数目而是物理存储容量的时候可以选择附加相应标志位来调用上述工具之一。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值