磁盘空间总是一种有限资源。我们监视磁盘使用情况,了解何时空间捉襟见肘,然后找到大体积的文件或目录,将其删除、移动或压缩。这则攻略将会讲解磁盘监视相关的命令。

9.2.1 预备知识

du(disk usage)df(disk free)命令可以报告磁盘使用情况。这两个工具能够统计出文件和目录的磁盘占用情况以及可用的磁盘空间。

9.2.2 实战演练

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

  1. $ du FILENAME1 FILENAME2 ..

例如:

  1. $ du file.txt
  1. [root@dev workspace]# du input.txt
  2. 4 input.txt
  3. [root@dev workspace]#

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

  1. $ du -a DIRECTORY
  1. [root@dev workspace]# du -a ./vitest
  2. 4 ./vitest/host.txt
  3. 4 ./vitest/test.sh
  4. 8 ./vitest/man_db.conf
  5. 20 ./vitest
  6. [root@dev workspace]# ls
  7. archive.tar.gz golang output.txt sample1.txt temp.txt variables.sh welcome.txt
  8. echo if.sh out.txt sample2.txt tools vitest
  9. else input.txt printf.sh showArgs.sh umq vitest.tar
  10. [root@dev workspace]# du ./vitest
  11. 20 ./vitest
  12. [root@dev workspace]#

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

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

例如:

  1. $ du -a ./vitest
  2. 4 ./vitest/host.txt
  3. 4 ./vitest/test.sh
  4. 8 ./vitest/man_db.conf
  5. 20 ./vitest

du命令也可以用于目录:

  1. $ du ./vitest
  2. 20 ./vitest

9.2.3 补充内容

du命令还包括了一些可以定义命令输出形式的选项。

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

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

  1. $ du -h FILENAME

例如:

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

或者

  1. # du -h DIRECTORY
  2. $ du -h hack/
  3. 16K hack/
  1. [root@dev workspace]# du -h ./vitest
  2. 20K ./vitest
  3. [root@dev workspace]# du -h input.txt
  4. 4.0K input.txt
  5. [root@dev workspace]#

显示磁盘使用总计

选项-c可以计算出文件或目录所占用的总的磁盘空间,另外还会输出单个文件的大小:

  1. $ du -c FILENAME1 FILENAME2..
  2. du -c process_log.sh pcpu.sh
  3. 4 process_log.sh
  4. 4 pcpu.sh
  5. 8 total

或者

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

或者

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

-c可以同-a-h等选项配合使用生成常见的输出,另外还会多出一行磁盘使用情况总计。

  1. [root@dev workspace]# du -c input.txt
  2. 4 input.txt
  3. 4 total
  4. [root@dev workspace]# du -c ./vitest
  5. 20 ./vitest
  6. 20 total
  7. [root@dev workspace]# du -ch ./vitest
  8. 20K ./vitest
  9. 20K total
  10. [root@dev workspace]# du -cah ./vitest
  11. 4.0K ./vitest/host.txt
  12. 4.0K ./vitest/test.sh
  13. 8.0K ./vitest/man_db.conf
  14. 20K ./vitest
  15. 20K total

另一个选项-s(summarize,总计)则只输出总计数据。它可以配合-h打印出人们易读的格式:

  1. [root@dev workspace]# du -sh ./vitest
  2. 20K ./vitest
  3. [root@dev workspace]# du -sh .
  4. 327M .
  5. [root@dev workspace]# ls
  6. archive.tar.gz golang output.txt sample1.txt temp.txt variables.sh welcome.txt
  7. echo if.sh out.txt sample2.txt tools vitest
  8. else input.txt printf.sh showArgs.sh umq vitest.tar
  9. [root@dev workspace]#

使用特定的单位打印文件

选项-b-k-m可以强制du使用特定的单位打印磁盘使用情况。注意,这些选项不能与-h一同使用:

  • 打印以字节(默认输出)为单位的文件大小:

    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. [root@dev workspace]# ls
  2. archive.tar.gz golang output.txt sample1.txt temp.txt variables.sh welcome.txt
  3. echo if.sh out.txt sample2.txt tools vitest
  4. else input.txt printf.sh showArgs.sh umq vitest.tar
  5. [root@dev workspace]# du -b input.txt
  6. 20 input.txt
  7. [root@dev workspace]# du -k input.txt
  8. 4 input.txt
  9. [root@dev workspace]# du -m input.txt
  10. 1 input.txt
  11. [root@dev workspace]# du -B 512 input.txt
  12. 8 input.txt
  13. [root@dev workspace]#

注意,上述选项返回的文件大小并不直观。如果使用选项-bdu会以字节为单位,返回文件的准确大小。如果使用的是其他选项,du返回的是文件所占的磁盘空间大小。因为磁盘空间是根据固定大小的块(通常是4K)来分配的,因此一个400字节的文件所占用的磁盘空间就是一个块(4K):

  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
  • 从磁盘使用统计中排除部分文件

选项--exclude--exclude-from可以让du在磁盘使用统计中排除部分文件。

  • 选项--exclude可以与通配符或单个文件名配合使用:
    1. $ du --exclude "WILDCARD" DIRECTORY
    例如:
  1. # 排除所有的.txt文件
  2. $ du --exclude "*.txt" *
  3. # 排除文件temp.txt
  4. $ du --exclude "temp.txt" *
  • 选项--exclude会排除匹配模式的一个或多个文件。选项--exclude-from能够排除多个文件或模式。每个文件名或模式必须独占一行。
    1. $ ls *.txt >EXCLUDE.txt
    2. $ ls *.odt >>EXCLUDE.txt
    3. # EXCLUDE.txt 中包含了需要排除的文件列表
    4. $ du --exclude-from EXCLUDE.txt DIRECTORY
    选项--max-depth可以限制du应该遍历多少层子目录。将该选项指定为1,可以统计当前目录的磁盘使用情况。指定为2,可以统计当前目录以及下一级子目录的磁盘使用情况:
    1. $ du --max-depth 2 DIRECTORY

    选项-x可以限制du只对单个文件系统进行统计。du默认会跟随符号链接和挂载点。

  1. [root@dev workspace]# du --max-depth 2 . #统计当前目录下一级目录
  2. 294928 ./tools/git-2.33.1
  3. 305020 ./tools
  4. 6860 ./golang/src
  5. 8200 ./golang/bin
  6. 13648 ./golang/pkg
  7. 28712 ./golang
  8. 20 ./vitest
  9. 333840 .
  10. [root@dev workspace]#

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

dusort命令能够找出需要被删除或移走的大文件:

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

选项-a可以显示出SOURCE_DIR中所有文件和目录的大小。输出的第一列就是文件大小。选项-k表示以KB为单位。第二列包含文件或目录的名称。

sort的选项-n指明按数值排序,选项-l-r指明对第一列按逆序排序。head用来从输出中提取前10行:

  1. $ du -ak . | sort -nrk 1 | head -n 10
  2. 333840 .
  3. 305020 ./tools
  4. 294928 ./tools/git-2.33.1
  5. 43864 ./tools/git-2.33.1/t
  6. 30056 ./tools/git-2.33.1/t/helper
  7. 29764 ./tools/git-2.33.1/libgit.a
  8. 28712 ./golang
  9. 22616 ./tools/git-2.33.1/po
  10. 21612 ./tools/git-2.33.1/git-reflog
  11. 18208 ./tools/git-2.33.1/builtin

这个单行脚本的缺点之一在于它的结果中还包含了目录。我们可以使用find命令改进脚本,使其只输出最大的文件:

  1. $ find . -type f -exec du -k {} \; | sort -nrk 1 | head -n 10
  2. 29764 ./tools/git-2.33.1/libgit.a
  3. 21612 ./tools/git-2.33.1/git-write-tree
  4. 21612 ./tools/git-2.33.1/git-worktree
  5. 21612 ./tools/git-2.33.1/git-whatchanged
  6. 21612 ./tools/git-2.33.1/git-verify-tag
  7. 21612 ./tools/git-2.33.1/git-verify-pack
  8. 21612 ./tools/git-2.33.1/git-verify-commit
  9. 21612 ./tools/git-2.33.1/git-var
  10. 21612 ./tools/git-2.33.1/git-upload-pack
  11. 21612 ./tools/git-2.33.1/git-upload-archive

利用finddu将文件过滤出来,这样就无需使用du遍历文件系统了。

注意du命令会输出文件的字节数。这个数字未必和文件所占的磁盘空间一样。磁盘空间是以块为单位分配的,因此就算是1字节的文件也会耗费一个磁盘块,块大小通常在5124096字节之间。

下一节将会讲解使用df命令确定可用的磁盘空间。

磁盘可用空间信息

du提供磁盘使用情况信息,而df提供磁盘可用空间信息。df-h选项会以易读的格式输出磁盘空间信息。例如:

  1. [root@dev workspace]# df -h
  2. Filesystem Size Used Avail Use% Mounted on
  3. /dev/sdc 251G 3.7G 235G 2% /
  4. tools 147G 112G 36G 76% /init
  5. none 3.9G 0 3.9G 0% /dev
  6. tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
  7. none 3.9G 0 3.9G 0% /run
  8. none 3.9G 0 3.9G 0% /run/lock
  9. none 3.9G 0 3.9G 0% /run/shm
  10. none 3.9G 0 3.9G 0% /run/user
  11. drivers 147G 112G 36G 76% /usr/lib/wsl/drivers
  12. lib 147G 112G 36G 76% /usr/lib/wsl/lib
  13. none 3.9G 4.0K 3.9G 1% /mnt/wsl
  14. none 3.9G 61M 3.8G 2% /mnt/wslg
  15. none 3.9G 76K 3.9G 1% /mnt/wslg/versions.txt
  16. none 3.9G 76K 3.9G 1% /mnt/wslg/doc
  17. drvfsa 147G 112G 36G 76% /mnt/c
  18. drvfsa 330G 125G 205G 38% /mnt/d
  19. [root@dev workspace]# df -h .
  20. Filesystem Size Used Avail Use% Mounted on
  21. /dev/sdc 251G 3.7G 235G 2% /
  22. [root@dev workspace]#

df命令也可以使用目录作为参数。在这种情况下,会输出该目录所在分区的可用磁盘空间情况。如果你不知道目录所在分区的话,这种方法就很有用了:

  1. [root@dev workspace]# df -h .
  2. Filesystem Size Used Avail Use% Mounted on
  3. /dev/sdc 251G 3.7G 235G 2% /