UNIX系统下监视磁盘空间和使用情况


    通常,UNIX® 管理员都拥有一套常用的辅助进程管理的实用工具、技巧和系统。本文提供了各种用于简化各个过程的关键实用工具、命令行链和脚本。这些工具中的一部分来自于操作系统,而大部分的技巧则来源于长期的经验积累和减轻系统管理员的工作压力的要求。本系列文章主要专注于最大限度地利用各种 UNIX 环境中可用的工具,包括简化异类环境中的管理任务的方法。
    入门:使用 df
    监视磁盘空间是 UNIX 管理员的工作中很重要的一部分。本文向您介绍一些完成管理工作所需的工具,包括 df、du、find 的使用,甚至配额的使用。让我们先来看看 df 的强大功能。
    对于许多管理员来说,使用 df 工具可能有点像断续的神经运动,因为它通过一个命令提供了所有文件系统中已使用的和可用的存储空间的快照视图。根据您的 UNIX 环境的不同,df 的缺省输出可能包含各种不同的信息。
    大部分现代的 df 变种都可以显示磁盘空间、使用情况和可用性,通常还包括装入点(有时包括设备)。例如,基于 BSD 的 Mac OS X 显示如清单 1 所示的信息。
    清单 1. Mac OS X 的缺省磁盘空间信息
    
Filesystem    512-blocks      Used     Avail Capacity  Mounted on
    /dev/disk0s2 268435456 119741344 148182112 45% /
    devfs 195 195 0 100% /dev
    fdesc 2 2 0 100% /dev
    <volfs> 1024 1024 0 100% /.vol
    清单 2. 使用带 -k 选项的 df 命令
    
$ df -k
    Filesystem 1K-blocks Used Avail Capacity Mounted on
    /dev/disk0s2 134217728 59870704 74091024 45% /
    devfs 97 97 0 100% /dev
    fdesc 1 1 0 100% /dev
    <volfs> 512 512 0 100% /.vol
    /dev/disk0s3 21737260 3625724 18111536 17% /Volumes/Untitled
    

    
    有些变种可能还支持可选的块大小,如兆字节(使用 -m)和千兆字节(使用 -g),如清单 3 所示。
    
     清单 3. 使用带 -g 选项的 df 命令
    
$ df -g
    Filesystem 1G-blocks Used Avail Capacity Mounted on
    /dev/disk0s2 128 57 70 45% /
    devfs 0 0 0 100% /dev
    fdesc 0 0 0 100% /dev
    <volfs> 0 0 0 100% /.vol
    /dev/disk0s3 20 3 17 17% /Volumes/Untitled
    

    
    很显然,在增大显示的块大小的同时,信息中的详细级别也开始降低,但使用可选的大小是一种快速监视磁盘,特别是超大容量磁盘的很有用的方法。其他版本的 df 工具(特别是 Solaris),缺省情况下将报告空块和文件可用性信息。大部分文件系统都具有能够存储文件的上限数值(该数值很大,以至于通常不会达到该上限),所以有可能整个系统填满了文件,还有可用磁盘容量但却不能再存储任何文件了。
    
    您可以在清单 4 中看到 Solaris 的缺省输出示例。
    
     清单 4. Solaris 的缺省输出
    
$ df
    / (/dev/dsk/c0t0d0s0 ):14877208 blocks 914042 files
    /devices (/devices ): 0 blocks 0 files
    /system/contract (ctfs ): 0 blocks 2147483618 files
    /proc (proc ): 0 blocks 16109 files
    /etc/mnttab (mnttab ): 0 blocks 0 files
    /etc/svc/volatile (swap ): 5737216 blocks 147177 files
    /system/object (objfs ): 0 blocks 2147483532 files
    /usr (/dev/dsk/c0t0d0s3 ): 9076010 blocks 863695 files
    /dev/fd (fd ): 0 blocks 0 files
    /var (/dev/dsk/c0t0d0s4 ): 8110796 blocks 483714 files
    /tmp (swap ): 5737216 blocks 147177 files
    /var/run (swap ): 5737216 blocks 147177 files
    /export/home (/dev/dsk/c0t0d0s7 ):69362510 blocks 4272812 files
    

    
    使用 -k 命令行选项可以将显示内容切换为与前面的示例类似的格式,其中对数据进行了摘要处理,得到更加便于阅读的格式(请参见清单 5)。
    
     清单 5. 使用 -k 选项
    
$ df -k
    Filesystem kbytes used avail capacity Mounted on
    /dev/dsk/c0t0d0s0 7644629 206026 7362157 3% /
    /devices 0 0 0 0% /devices
    ctfs 0 0 0 0% /system/contract
    proc 0 0 0 0% /proc
    mnttab 0 0 0 0% /etc/mnttab
    swap 2868600 1016 2867584 1% /etc/svc/volatile
    objfs 0 0 0 0% /system/object
    /dev/dsk/c0t0d0s3 8261237 3723232 4455393 46% /usr
    fd 0 0 0 0% /dev/fd
    /dev/dsk/c0t0d0s4 4130238 74849 4014087 2% /var
    swap 2867584 0 2867584 0% /tmp
    swap 2867624 40 2867584 1% /var/run
    /dev/dsk/c0t0d0s7 35611388 930133 34325142 3% /export/home
    

    
    所有的 df 变种都接受一个目录或路径,然后显示包含该路径的文件系统的磁盘空间信息。例如,下面显示了应该如何获得根文件系统的空间信息:
    
$ df -k /
    Filesystem kbytes used avail capacity Mounted on
    /dev/dsk/c0t0d0s0 7644629 206026 7362157 3% /
    

    
    或者,下面使用 df 显示了一个用户的 home 目录的空间信息:
    
$ df -k ~mc
    Filesystem kbytes used avail capacity Mounted on
    /dev/dsk/c0t0d0s7 35611388 930133 34325142 3% /export/home
    

    使用 df 的输出
    df 工具实际上是 disk free 的缩写,并且这也正是该工具所显示的内容。如果再次查看某个示例输出,您可以从中提取一些特别重要的元素:
    
Filesystem             kbytes    used    avail capacity  Mounted on
    /dev/dsk/c0t0d0s7 35611388 930133 34325142 3% /export/home
    

    第一列通常具有与块大小数据相对应的标题,它显示了磁盘的总大小。used 列显示了该文件系统或设备上已使用的块数。avail 列显示了该文件系统上尚未使用的(可用的)块数。
    capacity 列提供了总大小中已使用的磁盘空间所占的百分比。这个信息本身可以提供关于可用空间的直观指示。
    缺省情况下,UNIX 所创建的文件系统中百分之九十的容量可用于存放用户数据。剩下的百分之十由系统保留,以便 root 用户执行紧急维护工作。如果用户试图添加或创建超出该限制的文件,那么将返回一个错误(超出文件系统空间)。
    有了这个紧急维护空间,就可以利用它对一块已满的磁盘进行恢复。例如,作为管理员,您可以使用这个空间来创建快速备份,或对现有的数据进行压缩而无需为达到该目的使用辅助文件系统。您可以使用 tunefs 工具或在创建文件系统时,调整保留的空闲空间的大小。对于大容量磁盘来说,这是至关重要的,因为其中百分之十的缓冲区可能等于许多个 GB 的潜在空间。通常好的做法是至少保留百分之一的空间,以便在完全用尽存储空间之前,提供最低限度的缓冲区空间。在深入研究这个问题之前,特别是如果已经使用了大量的磁盘空间,您需要确定到底是谁使用了所有的这些空间。
    
    使用 du
    du 命令并不是显示磁盘的空闲空间,而是显示磁盘使用情况的信息。du 工具用于确定文件和目录的磁盘使用情况。要使用这个工具,改变到一个目录,然后运行该工具(请参见清单 6)。
    清单 6. du 命令
    
$ cd /var
    $ du
    16 ./lost+found
    4 ./sadm/install/admin
    22 ./sadm/install/logs
    28448 ./sadm/install
    4 ./sadm/pkg/SUNWocfd/install
    4 ./sadm/pkg/SUNWocfd/save/pspool/SUNWocfd/install
    16 ./sadm/pkg/SUNWocfd/save/pspool/SUNWocfd
    18 ./sadm/pkg/SUNWocfd/save/pspool
    20 ./sadm/pkg/SUNWocfd/save
    28 ./sadm/pkg/SUNWocfd
    4 ./sadm/pkg/SUNWcsu/inst
    ...
    

    上面的清单 6 中显示的输出,经过了适当的调整。缺省情况下,du 将显示当前或指定的目录下每个文件和目录的文件使用情况。得到的值是文件的大小,单位为该系统中的缺省块大小,与 df 所使用的单位相同。可能是也可能不是 1K,而使用 -k 命令行选项,您可以强制以 1K 块为单位进行显示。
    您可能需要根据所查看的顶级文件或目录对信息进行摘要。使用 -s 选项以打开摘要视图。下面是 Solaris 安装中的一个摘要版本在 /var 目录中的显示:
    
$ du -sk  
    70818 .
    

    请注意,它显示了当前目录 (.) 的摘要信息。要获得所有文件和目录的摘要信息,可以使用 * 通配符(请参见清单 7)。
    清单 7. 使用 * 通配符获得摘要信息
    
$ du -sk *
    382 adm
    950 apache
    683 apache2
    6837 appserver
    1 audit
    162 cache
    3 cc-ccr
    2 crash
    4 cron
    31 dmi
    22 dt
    6 fm
    2 imq
    1 inet
    3 krb5
    4 ld
    1 ldap
    937 lib
    6 log
    8 lost+found
    2 lp
    2 mail
    1 mysql
    1 news
    3 nfs
    38 nis
    2 ntp
    10034 opt
    1 preserve
    96 run
    49687 sadm
    15 saf
    3 samba
    2 sma_snmp
    131 snmp
    39 spool
    4 statmon
    663 svc
    14 tmp
    10 uucp
    24 yp
    

    使用该工具时,特别是在用户目录中使用该工具时,请特别小心,因为所显示的信息中不包含隐藏 文件,换句话说,具有单点号前缀的那些文件和目录。您可能希望使用下面的代码行,在用户目录中获得所有的摘要信息:
    
$ du -sk * .[a-zA-Z0-9]*
    

    du 命令的最后一个非常有用的选项是 -d,该选项可以防止 du 命令超过文件系统边界。例如,要确定根文件系统而不是任何其他的文件系统的磁盘使用情况,您可以使用 -d 选项:
    
$ du -dsk /
    

    有些系统没有这个选项,但是有 -x 命令行选项,该选项仅包含与您所指定的路径相同的设备或文件系统中的文件使用情况。
    查找一个特定用户的磁盘使用情况
    要查找某个用户所使用的磁盘空间,在使用 find 命令的同时,您需要结合使用 du 命令以仅报告特定用户的磁盘使用情况。
    
$ find . -user mc -type f -exec du -k {} \;
    

    -user 选项允许您指定 find 将仅报告属于特定用户的文件。-type 选项强制 find 仅返回特定类型(在本示例中是文件)项目的路径,这样可以防止 du 包含目录,因为这些目录可能属于某个用户,但其中却包含了许多用户的文件。然后,对于查找到的每个路径,执行 du 命令以报告磁盘使用情况。
    要获得摘要信息,换句话说,即某个特定用户所使用的总空间,您可以使用 awk 对该信息进行总计,并打印出最后的值:
    
$ find . -user mc -type f -exec du -k {} \;|awk '{ s = 
     s+$1 } END { print "Total used: ",s }'
    Total used: 123721
    

    对于组,您可以根据相同的原则对 find 使用 -group 选项:
    
$ find . -group mcslp -type f -exec du -k {} \;|awk '{ s = s+$1 } END { print
     "Total used: ",s }'
    Total used: 542485
    

    然而,如果启用了磁盘配额,那么就有一种更简单的方法。
    
    使用配额
    配额系统以文件系统为单位,自动监视该文件系统中各个用户的磁盘使用情况。配额环境不仅允许您监视磁盘的使用情况,而且还允许设置相应的使用限制,在超过使用限制时提供警告或者更直接地禁止用户使用超过所分配的配额值的磁盘空间。下限(发出警告)称为软限制,而上限(禁止创建超过该限制的文件)称为硬限制。有些系统可能还允许您控制每个用户所拥有的文件的数目。
    在您的计算机上启动配额的确切方法取决于您所使用的操作系统。大多数 UNIX 系统在缺省情况下都包含配额的支持。Linux® 系统可能需要构建新的包含配额支持的内核。然而,通常大多数操作系统为每个文件系统使用一个称为 quotas 的文件,其中包含了对每个用户的空间使用限制。
    要启用配额,您首先需要创建该文件,并确保仅有 root 用户可以编辑该配额文件:
    
$ touch /export/home/quotas
    $ chmod 600 /export/home/quotas
    

    然后,使用 quotaon 命令启用配额功能:
    
$ quotaon /export/home
    

    最后,您必须为每个用户编辑适当的配额。可以使用 edquota 命令并指定相应的用户来完成这项任务:
    
$ edquota mc
    

    这将打开缺省的编辑器(或者 vi,如果您没有设置可选的编辑器),其中包含一个用来设置配额值的简单表格。在下面您可以看到,已为用户 home 目录文件系统启用了配额,并且软限制为 200,000KB,硬限制为 400,000KB。文件限制的设置为零,这表示没有设置限制,用户可以设置并创建任意数目的文件。
    
fs /export/home blocks (soft = 200000, hard = 400000) inodes (soft = 0,
     hard = 0)
    

    如果有更多的文件系统具有配额,那么您需要为这些文件系统配置更多的行。
    如果您需要对多个用户配置配额,那么可以首先为一个用户设置配额,然后对 edquota 使用 -p 命令行选项。这将使用指定的用户作为基础来创建新的用户。例如,要使用 mc 的设置为用户名 slp、tw 和 sh 设置配额,请执行下面的命令:
    
$ edquota -p mc slp tw sh 
    

    使用配额进行文件限制警告
    当用户创建一个超过其软限制的文件时,他们将会得到下面的警告:
    
quota_ufs: Warning: over disk limit (pid 1738, uid 101, inum 94, fs /export/home)
    

    请注意,留给用户 7 天的时间更正该问题,您可以使用 edquota -t 来更改这个期限。
    如果用户试图创建超过硬限制的文件,那么系统将终止写进程并根据相应的限制来截断该文件:
    
$ mkfile 210000k overlimit
    quota_ufs: over hard disk limit (pid 1843, uid 101, inum 130, fs
     /export/home)
    overlimit: initialized 191873024 of 215040000 bytes: Disc quota exceeded
    

    通过运行 quota 命令,任何用户都可以检查他们自己的配额限制和磁盘使用情况:
    
$ quota
    Over disk quota on /export/home, remove 199993K within 7.0 days
    

    配额管理
    使用 quota 命令,系统管理员可以检查任何用户的配额,您应该使用 -v 命令行选项以提供关于文件系统、使用情况和限制信息的完整报告(请参见清单 8)。
    清单 8. 使用 -v 选项
    
$ quota -v mc
    Disk quotas for mc (uid 101):
    Filesystem usage quota limit timeleft files quota limit
     timeleft
    /export/home 399993 200000 400000 6.9 days 151 0 0
    

    要获得某个文件系统中详细描述所有用户的磁盘和配额使用情况的报告,可以使用 repquota 命令,并指定要报告的文件系统(请参见清单 9)。
    清单 9. 使用 repquote 命令
    
$ repquota -v /export/home 
    /dev/dsk/c0t0d0s7 (/export/home):
     Block limits File limits
    User used soft hard timeleft used soft hard timeleft
    mc +- 399993 200000 400000 6.9 days 151 0 0
    

    要确保配额信息保持最新,您应该使用 quotacheck 命令。这将利用用来报告配额信息的配额信息对文件存储数据进行验证。您应该使用 cron 来自动地运行这项任务,每天一次比较合适(因为这个过程是比较耗时的)。
    
    配额的技巧和陷井
    配额系统提供了监视和自动管理的最佳组合,但是您应该注意启用了配额的文件系统以及您所设置的限制,因为它们可能会妨碍用户的工作,而不是控制他们的磁盘使用情况。
    例如,与您进行的使用配置相比,程序员可能需要更多的空间来构建一个应用程序。通过提供一个不受限制的编译区域(通过设置一个可选的临时目录),您可以在维持他们的 home 目录配额的同时避开这个问题,或者在设置很高的硬限制(甚至可能是该文件系统的最大容量)的同时,设置合适的软限制。
    其结果应该是当达到软限制时给出一个警告,而不会真正地实施硬限制。用户应该仍然可以构建和创建临时文件,但是因为在构建的过程中会删除这些文件,所以不应该禁止用户创建他们所需的文件。
    配额还可以用来帮助完成监视任务,并提醒您关于特殊用户帐户的空间使用情况。我过去曾使用配额来监视 Web 用户帐户,即所谓的 nobody 帐户和其他帐户,以确保它们无法向不应具有访问权限的文件系统中写入文件。要完成这项任务,可以将您需要保护的文件系统和用户的硬限制设置为 1KB。
    自动监视
    手动监视磁盘空间使用情况是可行的,但是您并不希望不停地运行 df(甚至 du)来确定已使用的或可用的磁盘空间。您可以使这个过程自动化,并且当可用空间降低到一定的级别时,自动地向管理员(或者管理员组)发送电子邮件。清单 10 中的脚本用来监视磁盘空间,您可以设置警告 (warninglimit) 和紧急情况 (lowlimit) 限制,以及进行检查的文件系统的列表。
    清单 10. 监视磁盘空间
    
#!/bin/sh
    warninglimit=500000
    lowlimit=250000
    filesystems="/export/data /export/home /"
    for fs in $filesystems
    do
     size=`df -k $fs|grep $fs|awk '{ print $4; }'`
     if [ $size -le $lowlimit ]
     then
     mailx -s "URGENT: Low disk space for $fs ($size)"
     break
     fi
     if [ $size -le $warninglimit ]
     then
     mailx -s "WARNING: Low disk space for $fs ($size)"
    fi
    done
    

    其中关键的一行是提取每个文件系统中空闲磁盘空间的大小:
    
size=`df -k $fs|grep $fs|awk '{ print $4; }'`
    

    该脚本使用 df 仅提取了要进行 grep 的行,然后使用 awk 提取数据的第 4 列,该列是空闲空间的大小。
    然后,您可以根据 warninglimit/lowlimit 来检查空闲空间,并生成合适的错误。要避免系统同时发生下限和警告错误,该脚本首先检查下限,并在尝试测试警告之前使用 break 跳到循环中的下一个文件系统。
    结束语
    监视磁盘空间是管理员的一项重要工作,耗尽磁盘空间将可能严重地影响用户的工作,并且在严重的情况下,可能会丢失数据,或者使得系统崩溃,因为系统无法获得运行所需的磁盘空间。
    使用 df,您可以确定整个文件系统的空闲空间和空间使用情况,但这只是描述了部分信息。要确定磁盘空间用于何处,您需要使用 du 工具对不同的目录进行研究。通过使用 find,您甚至可以使用 du 来查找指定用户所使用的空间。对于更加自动化的用户级磁盘使用情况和控制,配额是一个更好的选择。