8.2 统计磁盘的使用情况

磁盘空间是一种有限资源。我们经常要统计硬盘或其他存储介质的使用情况,以便确定磁盘上的可用空间。当磁盘可用空间开始变少时,我们就得找到大体积的文件,删除或移走它们,以便腾出空间。磁盘使用管理多用于shell脚本环境。这则攻略将讲解用于磁盘管理和问题排除的各种命令,通过这些命令的不同选项可以统计磁盘的使用情况。

8.2.1 新手上路

dfdu是Linux中用于统计磁盘使用情况的重要命令。df是disk free的缩写,du是disk usage的缩写。让我们看看如何用它们执行各种涉及磁盘使用情况的任务。

8.2.2 实战演练

找出某个文件(或多个文件)占用的磁盘空间:

  1. $ du FILENAME1 FILENAME2 ..

例如:

  1. $ du file.txt
  2. 4

8.2 统计磁盘的使用情况 - 图1 统计结果默认以字节作为计算单位。

要获得某个目录中所有文件的磁盘使用情况,并在每一行中显示各个文件的磁盘占用详情,可以使用:

  1. $ du -a DIRECTORY

-a递归地输出指定目录或多个目录中所有文件的统计结果。

8.2 统计磁盘的使用情况 - 图2 执行du DIRECTORY也可以输出类似的结果,但是它只会显示子目录使用的磁盘空间,而不显示每个文件占用空间的情况。要想显示文件的磁盘使用情况,必须使用 -a

例如:

  1. $ du -a test
  2. 4 test/output.txt
  3. 4 test/process_log.sh
  4. 4 test/pcpu.sh
  5. 16 test

使用du DIRECTORY的输出如下:

  1. $ du test
  2. 16 test

8.2.3 补充内容

让我们看看du命令的其他用法。

  • 以KB、MB或块(block)为单位显示磁盘使用情况

命令du默认显示文件占用的总字节数,但是以标准单位KB、MB或GB显示磁盘使用情况更方便人们阅读。要采用这种更友好的格式进行打印,可以使用选项 -h

  1. du -h FILENAME

例如:

  1. $ du -sh test/pcpu.sh
  2. 4.0K test/pcpu.sh
  3. # 可以接受多个文件参数

或者

  1. # du -h DIRECTORY
  2. $ du -h hack/
  3. 16K hack/
  • 显示磁盘使用总计

假如我们需要计算所有文件或目录总共占用了多少磁盘空间,那么显示单个文件的使用情况显然没什么用。du的选项 -c可以输出作为命令参数的所有文件和目录的磁盘使用情况总计,它会在输出结果末尾加上一行总计。其使用语法如下:

  1. $ du -c FILENAME1 FILENAME2..

例如:

  1. du -c process_log.sh pcpu.sh
  2. 4 process_log.sh
  3. 4 pcpu.sh
  4. 8 total

或者

  1. $ du -c DIRECTORY

例如

  1. $ du -c test/
  2. 16 test/
  3. 16 total

或者

  1. $ du -c *.txt
  2. # 通配符

-c可以同 -a-h等选项组合使用。如果不使用-c,也可以得到同样的输出。唯一不同的是选项-c会添加一行磁盘使用情况总计。

另一个选项 -s(summarize,合计)则只输出合计数据。它可以配合 -h打印出人们易读的格式。这个命令在实践中经常使用,其语法如下:

  1. $ du -s FILES(s)
  2. $ du -sh DIRECTORY

例如:

  1. $ du -sh slynux
  2. 680K slynux
  • 用特定的单位打印文件

我们可以强制du使用特定的单位打印磁盘使用情况。举例如下。

  • 打印以字节(默认输出)为单位的文件大小:
  1. $ du -b FILE(s)
  • 打印以KB为单位的文件大小:
  1. $ du -k FILE(s)
  • 打印以MB为单位的文件大小:
  1. $ du -m FILE(s)
  • 打印以指定块为单位的文件大小:
  1. $ du -B BLOCK_SIZE FILE(s)

其中BLOCK_SIZE以字节为单位。

下面的例子中综合了这些命令:

  1. $ du pcpu.sh
  2. 4 pcpu.sh
  3. $ du -b pcpu.sh
  4. 439 pcpu.sh
  5. $ du -k pcpu.sh
  6. 4 pcpu.sh
  7. $ du -m pcpu.sh
  8. 1 pcpu.sh
  9. $ du -B 4 pcpu.sh
  10. 1024 pcpu.sh
  • 从磁盘使用统计中排除部分文件

有时候我们需要从磁盘使用统计中排除部分文件。可以使用两种方法指定需要排除的文件:

  • 通配符

按照下面的方法指定一个通配符:

  1. $ du --exclude "WILDCARD" DIRECTORY

例如:

  1. $ du --exclude "*.txt" FILES(s)
  2. # 排除所有的.txt文件
  • 排除列表

从文件中获取需要排除的文件列表:

  1. $ du --exclude-from EXCLUDE.txt DIRECTORY
  2. # EXCLUDE.txt包含了需要排除的文件列表

还有其他的选项可以很方便地用来限制磁盘使用统计的范围。我们可以用 --max-depth指定du应该遍历的目录层次的最大深度。将深度指定为1,可以统计当前目录下的所有文件占用内存的情况。将深度指定为2,可以统计当前目录以及下一级子目录中文件占用内存的情况,但不包括第二级子目录。

例如:

  1. $ du --max-depth 2 DIRECTORY

8.2 统计磁盘的使用情况 - 图3 可以用选项-x来限制du,使它只能够对单个文件系统进行遍历。假设运行du DIRECTORY,它会递归地遍历每一个可能存在的子目录。目录层次中的某个子目录可能就是一个挂载点(例如,/mnt/sda1是 /mnt的子目录,同时也是设备/dev/sda1的挂载点)。du会遍历挂载点并统计设备文件系统的磁盘使用情况。为了避免du的这种行为,可以在使用du其他选项的同时加上选项 -xdu -x /会将/mnt中的所有挂载点排除在磁盘使用统计之外。

当使用du时,要确保对其遍历的目录和文件拥有适合的读权限。

  • 找出指定目录中最大的10个文件

我们经常会碰上找出大体积文件的活儿,一般是要将这些大文件删除或移走。我们可以用dusort轻松地完成这项任务。下面的单行脚本就是其实现方法:

  1. $ du -ak SOURCE_DIR | sort -nrk 1 | head

其中,-a指定了所有的目录和文件。因此du会遍历SOURCE_DIR并计算所有文件的大小。由于指定了选项-k,输出的第一列会包含以KB为单位的文件大小,第二列则会包含文件或文件夹的名称。

sort对第一列依数值逆序排序。head用来显示前10行输出。

例如:

  1. $ du -ak /home/slynux | sort -nrk 1 | head -n 4
  2. 50220 /home/slynux
  3. 43296 /home/slynux/.mozilla
  4. 43284 /home/slynux/.mozilla/firefox
  5. 43276 /home/slynux/.mozilla/firefox/8c22khxc.default

上面这个单行脚本的缺点在于它在结果中包含了目录。如果我们只是需要找出最大的文件而不是目录的话,我们可以按照下面的方法改进脚本,使它只输出最大的文件:

  1. $ find . -type f -exec du -k {} \; | sort -nrk 1 | head

我们利用finddu将文件过滤出来,而无需du本身进行递归遍历。

  • 磁盘可用空间信息

du提供磁盘使用情况信息,而df提供磁盘可用空间信息。该命令用或不用选项-h皆可。如果使用-hdf则会以易读的格式打印磁盘空间信息。

例如:

  1. $ df
  2. Filesystem 1K-blocks Used Available Use% Mounted on
  3. /dev/sda1 9611492 2276840 6846412 25% /
  4. none 508828 240 508588 1% /dev
  5. none 513048 168 512880 1% /dev/shm
  6. none 513048 88 512960 1% /var/run
  7. none 513048 0 513048 0% /var/lock
  8. none 513048 0 513048 0% /lib/init/rw
  9. none 9611492 2276840 6846412 25% /var/lib/
  10. ureadahead/debugfs
  11.  
  12. $ df -h
  13. FilesystemSize Used Avail Use% Mounted on
  14. /dev/sda1 9.2G 2.2G 6.6G 25% /
  15. none 497M 240K 497M 1% /dev
  16. none 502M 168K 501M 1% /dev/shm
  17. none 502M 88K 501M 1% /var/run
  18. none 502M 0 502M 0% /var/lock
  19. none 502M 0 502M 0% /lib/init/rw
  20. none 9.2G 2.2G 6.6G 25% /var/lib/ureadahead/debugfs