Hack 和 / - 一点春季大扫除

作者:Kyle Rankin

无论你的硬盘有多大,在某个时候,你都会查看你的存储空间,并想知道所有的空间都去哪儿了。你的 /home 目录可能就是一个很好的例子。如果你像我一样,你并不总是在自己用完东西后清理干净,或者在下载文件后立即整理。当然,我有目录来整理我的 ISO 文件、我的文档和我的视频,但通常情况下,我的 home 目录变成了数字版的杂物抽屉,这里有一些 tarball 文件,那里有一个旧的发行版 ISO 文件,还有一些我不再拥有的硬件的 PDF 规格书。虽然其中一些文件实际上并不占用磁盘空间——更多的是杂乱无章——但当我的存储空间快用完时,我想找到占用空间最多的文件,并快速决定如何处理它们。本月,我将介绍一些我最喜欢的命令,用于查找系统上浪费空间的文件,并介绍一些常用的清理空间的方法。

本地思考

首先,让我们从你主目录中的文件杂乱开始。虽然现在所有主要的 GUI 文件管理器都可以轻松地按大小对目录进行排序,但因为我专注于命令行技巧,所以让我们介绍一下如何通过旧的 `ls` 命令在当前目录中查找最大的文件。如果你输入

$ ls -lSh

你将得到当前目录中所有文件的列表,并按大小排序。当然,如果你的目录中有很多文件,你最想看到的文件可能在列表的顶部附近,所以我通常喜欢输入

$ ls -lSh | less

以缓慢地查看列表,从顶部开始。或者,如果我赶时间,我会输入

$ ls -lSh | head

只查看前十个最大的文件。现在,这非常基础,但值得回顾,因为你会一遍又一遍地使用这些命令来追踪浪费空间的文件。根据你组织 home 目录的方式,你可能不会将所有大文件都放在一起。更可能的是,它们分散在不同的子目录中,因此你需要递归地扫描你的目录结构,统计每个目录中使用的磁盘空间,并对输出进行排序。幸运的是,你不需要求助于 `ls` 来完成这项工作;`du` 命令可以很好地完成这项工作。例如,我经常看到引用的 `du` 命令的一个常见用途是以下命令

$ du -sh *

这会扫描你列为参数的所有子目录(在本例中,是我当前目录中的所有子目录),然后逐个列出它们,并带有人类可读的文件大小(`-h` 选项将文件大小转换为兆字节、千兆字节等等,使其更易于阅读)。以下是该命令的一些示例输出

456K    bin
28K     Default-Compiz
16K     hl4070cdwcups-1.0.0-7.i386.deb
344K    hl4070cdwlpr-1.0.0-7.i386.deb
27M     images
60K     LexmarkC750.ppd
850M    mail

虽然你当然可以使用这些信息,但如果它被排序,将会更容易得多。要做到这一点,将 `-h` 参数替换为 `-k`,然后将输出通过管道传递给 `sort` 命令

$ du -sk * | sort -n

16      hl4070cdwcups-1.0.0-7.i386.deb
28      Default-Compiz
60      LexmarkC750.ppd
344     hl4070cdwlpr-1.0.0-7.i386.deb
456     bin
10224   writing
26948   images
869588  mail

这效果更好,因为现在我可以清楚地看到我的本地电子邮件缓存占用了大部分存储空间;但是,接下来我需要更改到邮件目录并再次运行该命令,一遍又一遍,直到我缩小范围到具有大文件的子目录。这就是为什么我通常跳过上面的命令,直接使用我亲切地称之为 “duck 命令” 的命令

$ du -ck | sort -n
. . .
87704   ./.mozilla
87704   ./.mozilla/firefox
119236  ./mail/example.net/sent-mail-2004
119236  ./mail/example.net/sent-mail-2004/cur
869852  ./mail
869852  ./mail/example.net
1064100 .
1064100 total

`-c` 选项本质上像以前一样递归到每个子目录中,除了它会持续统计树中每个子目录使用的空间,而不仅仅是第一级目录。当它报告其发现时,它可能会多次列出相同的顶级目录。这使得很容易深入到实际占用最多空间的目录,在本例中,似乎是 ./mail/example.net/sent-mail-2004/cur。如果我想清理那里的文件,我可以cd到该目录,然后运行我上面使用的 `ls` 命令,以查看哪些文件占用了最多的空间。

全局行动

“duck 命令” 非常适合发现你的 home 目录中的空间是如何被使用的,但如果你像我一样,你的 home 目录实际上与根文件系统位于不同的分区上。如果根目录正在被填满,你仍然可以使用 “duck 命令”(稍作调整)来查看哪些目录占用了最多的空间。你需要 root 权限才能扫描根文件系统中的所有目录,因此请使用susudo -s(取决于你如何获得 root 权限)在 “duck 命令” 之前

# cd /
# du -ckx | sort -n
. . .
243920  ./usr/lib/openoffice
277600  ./var/cache/apt
296376  ./var/cache
475144  ./var
952096  ./usr/share
1099264 ./usr/lib
2259332 ./usr
2908804 .
2908804 total

我上面添加的额外的 `-x` 参数告诉 `du` 命令停留在一个文件系统上——在本例中,是根文件系统。否则,如果你不指定 `-x`,并且你的 /home 或其他目录位于不同的文件系统上,`du` 命令也会扫描这些分区,因此你最终将不得不跳过它们,因为你要扫描你的结果。正如你从这个输出中看到的,`/usr` 目录占用了我系统上的大部分空间,其中 `/usr/lib` 几乎占用了 `/usr` 内部空间的一半。另请注意,`/var/cache/apt` 也在这里列出——下面将详细介绍如何处理它。

释放空间

既然你知道你的存储空间是如何被使用的,这里有一些常识性的方法来管理这些文件并释放一些空间。如果你进行 Linux 编程,从源代码构建软件,或者定期下载 tarball 文件,你可能有很多 tarball 文件以及它们解压后的目录散落在各处。释放空间的一种简单方法是删除 tarball 文件或解压后的目录。如果你构建自己的内核,你可能在 `/usr/src` 中有许多旧的内核源代码树,你永远不会再使用它们,并且可以删除它们。

另一个常见的空间浪费者是旧的 ISO 文件。你真的还需要 Red Hat 7.2 ISO 文件吗?如果需要,刻录一两个存档副本到 CD 中,然后删除映像。同样,音频文件总是最终在 mix CD 的目录中有一个额外的副本,或者如果你像我一样使用视频转换工具,你会有处于不同转码阶段的视频文件。如果你已经完成了一个项目,为什么不删除它们并节省空间呢?

在台式机上,尤其是在服务器上,你最常发现浪费空间的地方之一是日志目录。日志肯定是有用的,但有些日志和某些级别的调试只在发现错误后立即有用;其余时间,它们可以被截断或安全地存档。查看 `/var/log/`,看看你有多少大的未压缩的日志文件。如果该文件不再被使用,你应该使用 gzip 压缩它。如果你以前没有尝试过,你会惊讶于你可以压缩非常大的日志文件到什么程度。如果你不确定日志文件是否仍在写入,请使用 `lsof` 命令检查

# lsof | grep "/path/to/filename"

如果你经常发现自己在清理或 gzip 压缩 `/var/log` 中轮换的日志文件(它们在轮换时会附加 .0、.1 等后缀),那么编辑 `/etc/logrotate.conf` 并启用压缩。通常,这只需要找到标记为#compress的注释行并取消注释即可。

另一个释放空间的绝佳位置是你的软件包管理器的本地软件包缓存。例如,在基于 Debian 的系统中,apt 下载的软件包缓存在 `/var/cache/apt/archives` 中。你可以转到该目录并手动删除文件,或者你可以直接成为 root 用户并输入

# apt-get autoclean

来删除所有你不再需要的缓存软件包。如果你有一个使用 yum 的发行版,以下两个命令将清除系统中的缓存头文件和软件包

# yum clean headers
# yum clean packages

最后,当清理你的存储空间时,存档可能是一个很好的解决方案。如果你有一个本地文件服务器或一台比其他机器存储空间更大的机器,为什么不确保所有的大文件只存在于那里,然后通过网络访问它们呢?或者,将你想要保留但不需要立即使用的大文件刻录到 CD 或 DVD 中。一旦你完成这些操作,你将拥有大量新释放的空间——希望足够你用到明年春天。

Kyle Rankin 是旧金山湾区的高级系统管理员,也是包括 O'Reilly Media 出版的 Knoppix HacksUbuntu Hacks 在内的多本书籍的作者。他目前是北湾 Linux 用户组的主席。

加载 Disqus 评论