【问题标题】:Tracking down where disk space has gone on Linux?追踪 Linux 上磁盘空间的去向?
【发布时间】:2010-09-07 03:06:21
【问题描述】:

在管理 Linux 系统时,我经常发现自己在分区已满后努力追查罪魁祸首。我通常使用du / | sort -nr,但在大型文件系统上,这需要很长时间才能返回任何结果。

此外,这通常可以成功突出最严重的违规者,但我经常发现自己在没有 sort 的情况下诉诸 du 在更微妙的情况下,然后不得不对输出进行拖网。

我更喜欢依赖标准 Linux 命令的命令行解决方案,因为我必须管理相当多的系统并且安装新软件很麻烦(尤其是在磁盘空间不足时!)

【问题讨论】:

    标签: command-line partition disk-usage command


    【解决方案1】:

    试试ncdu,一个出色的命令行磁盘使用分析器:

    【讨论】:

    • 通常情况下,我讨厌被要求安装一些东西来解决一个简单的问题,但这很好。
    • sudo apt install ncdu 在 ubuntu 上轻松搞定。太棒了
    • 您很可能知道哪个文件系统空间不足。在这种情况下,您可以使用ncdu -x 仅计算与被扫描目录位于同一文件系统上的文件和目录。
    • 最佳答案。另外:sudo ncdu -rx / 应该只在根区域驱动器上对最大的目录/文件进行干净的读取。 (-r = 只读,-x = 留在同一个文件系统上(意思是:不要遍历其他文件系统挂载)
    • 空间太小,无法安装ncdu
    【解决方案2】:

    不要直接去du /。使用df 找到伤害您的分区,然后尝试du 命令。

    我喜欢尝试的是

    # U.S.
    du -h <dir> | grep '[0-9\.]\+G'
    # Others
    du -h <dir> | grep '[0-9\,]\+G'
    

    因为它以“人类可读的形式”打印尺寸。除非您的分区非常小,否则 grepping 以千兆字节为单位的目录是您想要的一个非常好的过滤器。这将花费您一些时间,但除非您设置了配额,否则我认为这就是它的方式。

    正如@jchavannes 在 cmets 中指出的那样,如果您发现太多误报,表达式会变得更加精确。我采纳了这个建议,确实让它变得更好,但仍然存在误报,所以只有权衡(更简单的 expr,更差的结果;更复杂和更长的 expr,更好的结果)。如果您的输出中显示了太多小目录,请相应地调整您的正则表达式。例如,

    grep '^\s*[0-9\.]\+G'
    

    更准确(不会列出

    如果你确实有配额,你可以使用

    quota -v
    

    查找占用磁盘的用户。

    【讨论】:

    • 这个非常快捷,简单实用
    • grep '[0-9]G' 包含很多误报,并且还省略了任何小数。这对我来说效果更好:sudo du -h / | grep -P '^[0-9\.]+G'
    • @jchavannes -P 对于这个表达式是不必要的,因为那里没有特定于 Perl 的东西。此外,-P 不能移植到没有 GNU 实现的系统。
    • 如果您的目录非常大,您需要[GT] 而不仅仅是G
    • 我喜欢用du -h | sort -hr | head
    【解决方案3】:

    首先,请使用du 的“摘要”视图:

    du -s /*
    

    效果是打印每个参数的大小,即上述案例中的每个根文件夹。

    此外,GNU duBSD du 都可以进行深度限制 (but POSIX du cannot!):

    • GNU(Linux,...):

      du --max-depth 3
      
    • BSD(macOS,...):

      du -d 3
      

    这将将输出显示限制到深度 3。当然,计算和显示的大小仍然是整个深度的总和。但尽管如此,限制显示深度会大大加快计算速度。

    另一个有用的选项是-h(GNU 和 BSD 上的单词,但同样,不是仅 POSIX 上的du)用于“人类可读”输出(即使用 KiB,MiB etc.)。

    【讨论】:

    • 如果du 抱怨-d 尝试--max-depth 5
    • 很棒的答案。对我来说似乎是正确的。我建议du -hcd 1 /directory。 -h 表示人类可读,c 表示总和 d 表示深度。
    • 我正在使用du -hd 1 &lt;folder to inspect&gt; | sort -hr | head
    • du --max-depth 5 -h /* 2&gt;&amp;1 | grep '[0-9\.]\+G' | sort -hr | head 过滤权限被拒绝
    【解决方案4】:

    您还可以使用du 运行以下命令:

    ~# du -Pshx /* 2>/dev/null
    
    • -s 选项汇总并显示每个参数的总数。
    • -h 打印 Mio、Gio 等。
    • -x = 留在一个文件系统中(非常有用)。
    • -P = 不要遵循符号链接(例如,这可能导致文件被计算两次)。

    小心-x,如果/root 目录位于不同的文件系统上,它不会显示它。在这种情况下,您必须运行 du -Pshx /root 2&gt;/dev/null 来显示它(曾经,我费了很大劲才指出我的 /root 目录已满)。

    【讨论】:

    • du -Pshx .* * 2&gt;/dev/null + 隐藏/系统目录
    • /root/shows 没有问题。为什么不显示?
    【解决方案5】:

    在文件系统上查找最大的文件总是需要很长时间。根据定义,您必须遍历整个文件系统以查找大文件。唯一的解决方案可能是在所有系统上运行 cron 作业以提前准备好文件。

    另外,du 的 x 选项对于防止 du 跟随挂载点进入其他文件系统很有用。即:

    du -x [path]
    

    我通常运行的完整命令是:

    sudo du -xm / | sort -rn > usage.txt
    

    -m 表示以兆字节为单位返回结果,sort -rn 会将结果排在第一位。然后,您可以在编辑器中打开 usage.txt,最大的文件夹(以 / 开头)将位于顶部。

    【讨论】:

    • 感谢您指出-x 标志!
    • "找到最大的需要很长时间.." -> 这取决于,但往往不同意:使用像 ncdu 这样的实用程序不需要那么长时间 - 至少比 du 或 @ 快987654328@(取决于深度和参数)..
    • 因为我不想成为 root,所以我不得不调整文件的写入位置:sudo du -xm / | sort -rn &gt; ~/usage.txt
    【解决方案6】:

    我总是使用du -sm * | sort -n,它为您提供当前工作目录的子目录使用量的排序列表,以兆字节为单位。

    您也可以尝试 Konqueror,它具有“大小视图”模式,类似于 WinDirStat 在 Windows 上所做的:它为您提供了哪些文件/目录占用了大部分空间的可视化表示。

    更新:在更新的版本中,您还可以使用du -sh * | sort -h,它将显示人类可读的文件大小并按这些大小排序。 (数字后缀为 K、M、G、...)

    对于寻找 KDE3 的 Konqueror 文件大小视图替代方案的人来说,可以看看 filelight,虽然它不是那么好。

    【讨论】:

    • 这只是 Konqueror 3.x - 文件大小视图仍然尚未移植到 KDE4。
    • 'du -sh * | sort -h ' 在我的 Linux (Centos 发行版) 机器上完美运行。谢谢!
    【解决方案7】:

    我将它用于当前目录下的前 25 个最严重的违规者

    # -S to not include subdir size, sorted and limited to top 25
    du -S . | sort -nr | head -25
    

    【讨论】:

    • 这个命令可以找到一个隐藏文件夹,该文件夹的大小似乎随着时间的推移而增加。谢谢!
    • 这是字节数吗?
    • 默认情况下,在我的系统上,'du -S' 提供了很好的人类可读输出。对于小文件,您会得到一个普通的字节数,对于大文件,您会得到一个带有“KB”或“MB”后缀的数字。
    • @Siddhartha 如果添加-h,它可能会改变sort -nr 命令的效果——意味着排序将不再起作用,然后head 命令也将不再起作用
    • 在 Ubuntu 上,我需要使用 -hdu 来进行人类可读的数字,以及使用 sort -h 来进行人类数字排序。该列表是反向排序的,因此请使用tail 或更改顺序。
    【解决方案8】:

    在以前的公司,我们曾经有一个 cron 作业,它会在一夜之间运行并识别任何超过一定大小的文件,例如

    find / -size +10000k
    

    您可能希望对正在搜索的目录更有选择性,并注意任何远程安装的驱动器可能会脱机。

    【讨论】:

    • 您可以使用 find 的 -x 选项来确保您在 find 命令的起点之外的其他设备上找不到文件。这解决了远程安装的驱动器问题。
    【解决方案9】:

    我用

    du -ch --max-depth=2 .
    

    我更改了最大深度以满足我的需要。 “c”选项打印文件夹的总数,“h”选项打印适当的 K、M 或 G 大小。正如其他人所说,它仍然扫描所有目录,但它以一种我发现更容易找到大目录的方式限制输出。

    【讨论】:

      【解决方案10】:

      一种选择是将您的 du/sort 命令作为 cron 作业运行,然后输出到文件中,以便在您需要时它已经存在。

      【讨论】:

        【解决方案11】:

        对于命令行,我认为 du/sort 方法是最好的。如果您不在服务器上,您应该查看Baobab - Disk usage analyzer。这个程序也需要一些时间来运行,但你可以很容易地找到所有旧 Linux ISO 所在的子目录。

        【讨论】:

        • 它还可以通过SSH、FTP、SMB和WebDAV扫描远程文件夹。
        • 这很棒。有些事情在 GUI 上可以更好地进行可视化,这就是其中之一!无论如何,我的服务器上都需要一个 X-server 用于 CrashPlan,所以它也适用。
        【解决方案12】:

        我要去第二个xdiskusage。但我要补充一点,它实际上是一个 du 前端,可以从文件中读取 du 输出。所以你可以在你的服务器上运行du -ax /home &gt; ~/home-du,返回scp文件,然后以图形方式分析它。或者通过 ssh 进行管道传输。

        【讨论】:

          【解决方案13】:

          尝试将 du 的输出输入到一个简单的 awk 脚本中,该脚本检查目录的大小是否大于某个阈值,如果是,则打印它。在开始获取信息之前,您不必等待遍历整个树(与许多其他答案相比)。

          例如,以下显示任何消耗超过 500 MB 的目录。

          du -kx / | awk '{ if ($1 > 500000) { print $0} }'
          

          为了使上述内容更可重用,您可以在 .bashrc 中定义一个函数,(或者您可以将其制成一个独立的脚本)。

          dubig() {
              [ -z "$1" ] && echo "usage: dubig sizethreshMB [dir]" && return
              du -kx $2 | awk '{ if ($1 > '$1'*1024) { print $0} }'
          }
          

          所以dubig 200 ~/ 在主目录下查找使用超过 200 MB 的目录(不跟踪设备外的符号链接)。

          【讨论】:

          • 遗憾的是,十几个 grep hack 的投票率更高。哦,du -k 将绝对确定 du 使用的是 KB 单位
          • 关于 -k 的好主意。已编辑。
          • 更简单、更健壮:du -kx $2 | awk '$1&gt;'$(($1*1024))(如果您只指定一个条件又名模式来 awk,则默认操作是 print $0
          • 好点@date_thompson_085。对于我所知道的所有 awk 版本(net/free-BSD 和 GNU)都是如此。 @mark-borgerding 所以这意味着您可以将第一个示例大大简化为 du -kx / | awk '$1 &gt; 500000'
          • @mark-borgerding:如果你只剩下几kBytes,你也可以像du -kx / | tee /tmp/du.log | awk '$1 &gt; 500000'一样保留du的整个输出。这非常有用,因为如果您的第一次过滤结果没有结果,您可以尝试像 awk '$1 &gt; 200000' /tmp/du.log 这样的其他值或像 sort -nr /tmp/du.log|less 这样检查完整的输出,而无需重新扫描整个文件系统
          【解决方案14】:

          我更喜欢使用以下内容来获得概述并从那里向下钻取...

          cd /folder_to_check
          du -shx */
          

          这将显示带有人类可读输出的结果,例如 GB、MB。它还将防止遍历远程文件系统。 -s 选项仅显示找到的每个文件夹的摘要,因此如果您对文件夹的更多详细信息感兴趣,可以进一步深入了解。请记住,此解决方案只会显示文件夹,因此如果您还需要文件,则需要省略星号后的 /。

          【讨论】:

            【解决方案15】:

            此处未提及,但您还应该检查 lsof 以防文件被删除/挂起。我从一个失控的 cronjob 中删除了 5.9GB 的 tmp 文件。

            https://serverfault.com/questions/207100/how-can-i-find-phantom-storage-usage 帮助我找到了所述文件 (cron) 的进程所有者,然后我能够转到/proc/{cron id}/fd/{file handle #} less 有问题的文件以开始逃跑,解决该问题,然后回显"" > 文件清理空间,让 cron 优雅地关闭自己。

            【讨论】:

              【解决方案16】:

              可能值得注意的是mc(Midnight Commander,一个经典的文本模式文件管理器)默认只显示目录 inode 的大小(通常是4096),但使用 CtrlSpace 或使用菜单工具,您可以以人类可读的格式查看所选目录占用的空间(例如,一些像103151M)。

              例如,下图显示了 2018 年和 2017 年的原版 TeX Live 发行版的完整大小,而 2015 年和 2016 年的版本仅显示了 inode 的大小(但它们实际上每个都接近 5 Gb)。

              CtrlSpace必须一对一做,只针对实际的目录层级,但是用@987654326导航的时候就是这么快又好用@ 那也许你不需要ncdu (确实,只为了这个目的更好)。否则,您也可以从mc 运行ncdu。无需从mc 退出或启动另一个终端。

              【讨论】:

                【解决方案17】:

                我喜欢旧的 xdiskusage 作为 du(1) 的图形替代品。

                【讨论】:

                • 请注意问题的这一部分:“我更喜欢依赖标准 Linux 命令的命令行解决方案,因为...”
                【解决方案18】:

                您可以使用findsort 等标准工具来分析您的磁盘空间使用情况。

                列出按大小排序的目录

                find / -mount -type d -exec du -s "{}" \; | sort -n
                

                列出按大小排序的文件

                find / -mount -printf "%k\t%p\n" | sort -n
                

                【讨论】:

                • 我发现这是最好的答案,可以按排序顺序检测大尺寸
                【解决方案19】:

                从终端,您可以使用dutree 获得磁盘使用情况的可视化表示

                因为它是用 Rust 实现的,所以非常快速和轻量

                $ dutree -h
                Usage: dutree [options] <path> [<path>..]
                
                Options:
                    -d, --depth [DEPTH] show directories up to depth N (def 1)
                    -a, --aggr [N[KMG]] aggregate smaller than N B/KiB/MiB/GiB (def 1M)
                    -s, --summary       equivalent to -da, or -d1 -a1M
                    -u, --usage         report real disk usage instead of file size
                    -b, --bytes         print sizes in bytes
                    -f, --files-only    skip directories for a fast local overview
                    -x, --exclude NAME  exclude matching files or directories
                    -H, --no-hidden     exclude hidden files
                    -A, --ascii         ASCII characters only, no colors
                    -h, --help          show help
                    -v, --version       print version number
                

                查看website中的所有使用详情

                【讨论】:

                  【解决方案20】:

                  我已经使用这个命令来查找大于 100Mb 的文件:

                  find / -size +100M -exec ls -l {} \;
                  

                  【讨论】:

                    【解决方案21】:

                    对于命令行 du (及其选项)似乎是最好的方法。 DiskHog 看起来也使用了来自 cron 作业的 du/df 信息,所以 Peter's suggestion 可能是简单和有效的最佳组合。

                    FileLightKDirStat 是 GUI 的理想选择。)

                    【讨论】:

                      【解决方案22】:

                      首先我检查目录的大小,如下所示:

                      du -sh /var/cache/*/
                      

                      【讨论】:

                        【解决方案23】:

                        如果您知道最近几天(比如 3 天)添加了大文件,那么您可以使用 find 命令和“ls -ltra”来发现最近添加的文件:

                        find /some/dir -type f -mtime -3 -exec ls -lart {} \;
                        

                        这只会给你文件(“-type f”),而不是目录;仅在过去 3 天内修改时间的文件 ("-mtime -3") 并对每个找到的文件执行 "ls -lart" ("-exec" 部分)。

                        【讨论】:

                          【解决方案24】:

                          要了解不成比例的磁盘空间使用情况,通常从根目录开始并遍历其一些最大的子目录通常很有用。

                          我们可以这样做

                          • 将 du 的输出保存到文件中
                          • 迭代地遍历结果

                          即:

                          # sum up the size of all files and directories under the root filesystem
                          du -a -h -x / > disk_usage.txt
                          # display the size of root items
                          grep $'\t/[^/]*$' disk_usage.txt
                          

                          现在假设 /usr 显得太大

                          # display the size of /usr items
                          grep $'\t/usr/[^/]*$' disk_usage.txt
                          

                          现在如果 /usr/local 太大了

                          # display the size /usr/local items
                          grep $'\t/usr/local/[^/]*$' disk_usage.txt
                          

                          等等……

                          【讨论】:

                            【解决方案25】:

                            还在这里吗?或者也许这个答案已被赞成......

                            虽然其他答案中描述了各种图形工具,但它们对于解决确定如何释放空间的潜在问题并没有太大作用。

                            我目前正在研究同样的问题并遇到了agedu - 它报告了访问时间和大小。我还没有机会玩它——它是由 Simon Tatham 写的(你可能听说过 PuTTy)所以可能是明智/可靠的。

                            但是,与此处列出的所有工具一样,它会按需收集数据。即使是在最快的硬件上进行最高效的编码,也需要时间来遍历一个 milt-terrabyte 文件系统。

                            【讨论】:

                            • 如果您不能使用 GUI(就像您在远程服务器上一样),ncdu -e 可以很好地工作。显示打开后,使用m 然后M 显示并按 mtime 排序,而(当然很小)百分比图仍然在那里让您了解大小。
                            • “如果您不能使用 GUI(就像您在远程服务器上一样),” - 为什么远程服务器会阻止您使用 gui?
                            • ncdu -e 是错误的,因为它需要一个参数
                            【解决方案26】:

                            另一个是duc,它是一种命令行工具的集合,它们确实具有可扩展性、快速性和通用性。它还具有一些 GUI/TUI 选项。

                            【讨论】:

                              【解决方案27】:

                              我已成功追踪最严重的违规者,将 du 输出以人类可读的形式传输到 egrep 并匹配正则表达式。

                              例如:

                              du -h | egrep "[0-9]+G.*|[5-9][0-9][0-9]M.*"
                              

                              这应该会给你 500 兆或更高的所有内容。

                              【讨论】:

                              • 不要使用 grep 进行算术运算——使用 awk 代替:du -k | awk '$1 &gt; 500000'。在第一次尝试时更容易理解、编辑和纠正。
                              【解决方案28】:

                              如果你想要速度,你可以在你想监控的文件系统上启用配额(你不需要为任何用户设置配额),并使用一个使用配额命令的脚本来列出每个用户正在使用的磁盘空间。例如:

                              quota -v $user | grep $filesystem | awk '{ print $2 }'
                              

                              将为您提供特定文件系统上特定用户的磁盘使用情况。通过这种方式,您应该能够在几秒钟内检查使用情况。

                              要启用配额,您需要将 usrquota 添加到 /etc/fstab 文件中的文件系统选项中,然后可能会重新启动,以便在调用 quotaon 之前可以在空闲文件系统上运行 quotacheck。

                              【讨论】:

                                【解决方案29】:

                                这是一个小型应用程序,它使用深度采样来查找任何磁盘或目录中的肿瘤。它遍历目录树两次,一次是测量它,第二次是打印出目录下 20 个“随机”字节的路径。

                                void walk(string sDir, int iPass, int64& n, int64& n1, int64 step){
                                    foreach(string sSubDir in sDir){
                                        walk(sDir + "/" + sSubDir, iPass, n, n1, step);
                                    }
                                    foreach(string sFile in sDir){
                                        string sPath = sDir + "/" + sFile;
                                        int64 len = File.Size(sPath);
                                        if (iPass == 2){
                                            while(n1 <= n+len){
                                               print sPath;
                                               n1 += step;
                                            }
                                        }
                                        n += len;
                                    }
                                }
                                
                                void dscan(){
                                    int64 n = 0, n1 = 0, step = 0;
                                    // pass 1, measure
                                    walk(".", 1, n, n1);
                                    print n;
                                    // pass 2, print
                                    step = n/20; n1 = step/2; n = 0;
                                    walk(".", 2, n, n1);
                                    print n;
                                }
                                

                                我的 Program Files 目录的输出如下所示:

                                 7,908,634,694
                                .\ArcSoft\PhotoStudio 2000\Samples\3.jpg
                                .\Common Files\Java\Update\Base Images\j2re1.4.2-b28\core1.zip
                                .\Common Files\Wise Installation Wizard\WISDED53B0BB67C4244AE6AD6FD3C28D1EF_7_0_2_7.MSI
                                .\Insightful\splus62\java\jre\lib\jaws.jar
                                .\Intel\Compiler\Fortran\9.1\em64t\bin\tselect.exe
                                .\Intel\Download\IntelFortranProCompiler91\Compiler\Itanium\Data1.cab
                                .\Intel\MKL\8.0.1\em64t\bin\mkl_lapack32.dll
                                .\Java\jre1.6.0\bin\client\classes.jsa
                                .\Microsoft SQL Server\90\Setup Bootstrap\sqlsval.dll
                                .\Microsoft Visual Studio\DF98\DOC\TAPI.CHM
                                .\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\sqlce20sql2ksp1.exe
                                .\Microsoft Visual Studio .NET 2003\SDK\v1.1\Tool Developers Guide\docs\Partition II Metadata.doc
                                .\Microsoft Visual Studio .NET 2003\Visual Studio .NET Enterprise Architect 2003 - English\Logs\VSMsiLog0A34.txt
                                .\Microsoft Visual Studio 8\Microsoft Visual Studio 2005 Professional Edition - ENU\Logs\VSMsiLog1A9E.txt
                                .\Microsoft Visual Studio 8\SmartDevices\SDK\CompactFramework\2.0\v2.0\WindowsCE\wce500\mipsiv\NETCFv2.wce5.mipsiv.cab
                                .\Microsoft Visual Studio 8\VC\ce\atlmfc\lib\armv4i\UafxcW.lib
                                .\Microsoft Visual Studio 8\VC\ce\Dll\mipsii\mfc80ud.pdb
                                .\Movie Maker\MUI\0409\moviemk.chm
                                .\TheCompany\TheProduct\docs\TheProduct User's Guide.pdf
                                .\VNI\CTT6.0\help\StatV1.pdf
                                7,908,634,694
                                

                                它告诉我目录是7.9gb,其中

                                • ~15% 用于英特尔 Fortran 编译器
                                • ~15% 用于 VS .NET 2003
                                • ~20% 用于 VS 8

                                询问这些是否可以卸载很简单。

                                它还讲述了分布在文件系统中的文件类型,但综合起来代表了节省空间的机会:

                                • ~15% 大约用于 .cab 和 .MSI 文件
                                • ~10% 大致用于记录文本文件

                                它还显示了很多其他我可能不需要的东西,比如“SmartDevices”和“ce”支持(~15%)。

                                这确实需要线性时间,但不必经常这样做。

                                它发现的例子:

                                • 在许多已保存的代码存储库中备份 DLL 副本,真的需要保存
                                • 服务器上某个不知名目录下某人硬盘的备份副本
                                • 大量临时 Internet 文件
                                • 古老的文档和帮助文件早已不再需要

                                【讨论】:

                                  【解决方案30】:

                                  我遇到了类似的问题,但此页面上的答案还不够。我发现以下命令对列表最有用:

                                  du -a / | sort -n -r | head -n 20

                                  这会告诉我 20 个最大的罪犯。但是,即使我运行了这个,它也没有告诉我真正的问题,因为我已经删除了该文件。 问题是有一个仍在运行的进程正在引用已删除的日志文件...所以我必须先终止该进程,然后磁盘空间显示为空闲。

                                  【讨论】:

                                  • 好点,但这应该是一个评论,而不是一个答案本身 - 这个问题有太多的答案
                                  猜你喜欢
                                  • 2020-10-20
                                  • 2020-07-12
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2019-04-12
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多