尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Linux磁盘空间排查:du与sort命令组合实战指南

Linux磁盘空间排查:du与sort命令组合实战指南 1. 从“我的硬盘去哪儿了”说起du与sort的黄金搭档不知道你有没有遇到过这种情况服务器或者自己的开发机用着用着突然就弹出“磁盘空间不足”的警告。看着满屏的文件和目录你根本不知道是哪个“大胃王”偷偷吃掉了宝贵的空间。这时候你可能会本能地打开文件管理器试图手动一个个文件夹去查看属性但在一个动辄包含成千上万个文件的Linux服务器上这无异于大海捞针。几年前我刚接手一个线上服务时就踩过这个坑。报警邮件半夜响起提示某台应用服务器磁盘使用率超过95%。登录上去一看/根目录下几十个文件夹/home、/var、/opt…… 每个下面又套着无数子目录。当时我对Linux命令还不熟情急之下差点想重启服务器碰碰运气。幸好一位前辈提醒“别慌先用du看看哪个目录最大再用sort排个序一眼就能找到罪魁祸首。” 我照做了命令很简单du -sh /* | sort -hr。结果立马显示/var/log目录占用了近80%的空间进去一看原来是一个被遗忘的调试服务产生了海量的日志文件且没有配置日志轮转。问题瞬间定位清理日志后空间立刻释放。自那以后dudisk usage和sort这两个命令就成了我日常运维和开发工作中的“黄金搭档”。它们单独使用已经很强大了但组合起来简直就是分析和清理磁盘空间的“手术刀”和“显微镜”。du负责精准测量每个目录的“体重”而sort则负责把这些体重数据按照从胖到瘦或从瘦到胖的顺序排列好让你一眼锁定目标。无论你是系统管理员、后端开发者还是数据工程师只要你的工作环境涉及Linux这套组合拳就是你必须掌握的生存技能。它不要求你有多高深的编程知识却能解决实实在在的、影响系统稳定性的核心问题。2. du命令详解不只是看看大小那么简单很多人对du命令的理解停留在du -sh查看当前目录总大小这个层面这就像只学会了汽车的启动和刹车远未发挥其全部性能。du命令的真正威力在于其丰富的选项可以让你从不同维度、不同深度去洞察磁盘空间的分布情况。2.1 核心选项拆解与使用场景du命令的选项很多但最常用、最核心的就那么几个。理解它们你就能应对绝大多数场景。-h(human-readable)这是必选项这是让du命令变得“友好”的关键。没有它du输出的数字单位是千字节(KiB)对于动辄几个G甚至几个T的现代存储来说一堆数字很难直观理解。加上-h后du会自动转换为K、M、G、T等人类可读的单位。例如4096会变成4.0K10485760会变成10M。我个人的习惯是几乎在所有情况下都加上-h除非在做需要精确字节数的脚本处理。-s(summarize)查看目录总览这个选项让du只显示指定目录的总大小而不深入列出其内部每一个子项。这是快速评估一个目录是否“肥胖”的最快方式。比如你想知道/home用户目录总共占了多大空间就用du -sh /home。如果不用-s它会递归列出/home下每个用户目录每个用户目录下每个文件夹…… 输出会又长又难以阅读。-d(max-depth)控制探测深度这是进行“分层诊断”的利器。-d后面跟一个数字表示深入到第几级子目录。例如在根目录/下执行du -h -d 1它会显示/下所有一级子目录如/bin,/home,/var的大小。这比-s更细致又比无深度限制的递归更清晰。场景对比du -sh /var只知道/var总大小。du -h -d 1 /var可以知道是/var/log大还是/var/cache大还是/var/lib大。du -h -d 2 /var可以进一步看到/var/log下面是/var/log/nginx大还是/var/log/syslog大。-a(all)连文件也不放过默认情况下du只显示目录的大小。但有时候一个目录本身不大里面却藏着一个巨大的单个文件比如一个数GB的数据库备份文件.sql。这时候-a选项就派上用场了它会同时列出目录和文件的大小。不过要注意这会让输出变得非常冗长通常需要结合sort和head来过滤。例如找出当前目录下最大的10个文件du -ah . | sort -rh | head -n 10。-c(total)最后来一个总计这个选项会在输出的最后一行加上所有列出项的总大小。在和-s一起使用时特别有用。比如du -sch /home/*它会列出/home下每个用户目录的大小并在最后给出一个总计。这在做空间统计报告时非常清晰。--exclude与--exclude-from排除干扰项磁盘分析中经常遇到一些“干扰项”比如虚拟文件系统/proc、/sys或者特定的缓存目录、版本控制目录如.git。直接扫描整个根目录可能会陷入这些特殊目录它们的大小显示可能异常或没有意义。--excludePATTERN可以排除匹配模式的文件或目录。实战例子你想分析根目录但排除/proc、/sys、/mnt这些挂载点命令可以写成du -sh --exclude/proc --exclude/sys --exclude/mnt /*。更复杂的情况你可以把要排除的模式写在一个文件里然后用--exclude-fromFILE来指定。2.2 理解“大小”背后的计算逻辑磁盘占用 vs 实际大小这里有一个非常重要的细节也是新手容易困惑的地方du命令默认显示的是“磁盘占用空间”而不是文件的“逻辑大小”。逻辑大小 (Apparent Size)就是文件内容实际有多少字节。可以用ls -l看到的那个大小。磁盘占用空间 (Disk Usage)是文件在磁盘上实际占用了多少块block。因为文件系统有“块大小”block size通常是4KB的概念即使一个文件只有1字节它也会独占一个4KB的块。举个例子你创建了一个1字节的文本文件。ls -lh file.txt可能显示1B逻辑大小。du -h file.txt很可能显示4.0K磁盘占用因为占了一个4KB的块。du命令之所以叫“disk usage”就是因为它汇报的是对磁盘空间的真实消耗这对于空间管理来说才是最有意义的。如果你想看逻辑大小du提供了--apparent-size选项但日常运维中极少使用。2.3 一个综合性的实战案例假设你是一台Web服务器的管理员收到告警/分区空间不足。你的排查思路可以是这样快速定位问题一级目录cd / sudo du -h -d 1 | sort -hr这条命令会列出根目录下所有一级子目录的大小并从大到小排序。你可能会立刻发现/var或者/home异常巨大。深入问题目录进行二级诊断 假设发现是/var很大。cd /var sudo du -h -d 1 | sort -hr现在你看到可能是/var/log或/var/lib很大。精准定位大文件或历史文件 进入/var/log你想找出最大的文件并看看有没有陈年老日志。cd /var/log # 找出最大的10个文件 sudo find . -type f -exec du -h {} | sort -rh | head -n 10 # 找出超过100M的文件 sudo find . -type f -size 100M -exec du -h {} \; # 找出30天前的日志文件 sudo find . -type f -name *.log -mtime 30 -exec ls -lh {} \;这里引入了find命令进行更复杂的过滤。你可能发现是某个access.log文件滚了几十GB或者一些旧的journal日志没清理。通过这个由浅入深的流程你就能像侦探一样层层剥茧最终找到吞噬磁盘空间的“元凶”。而这一切的起点就是熟练运用du命令的各种选项。3. sort命令精讲让杂乱数据瞬间有序如果说du是收集数据的侦察兵那么sort就是整理情报的分析师。它能够对文本行进行排序默认按照字典序lexicographical order升序排列。但面对du输出的带有K、M、G单位的数据默认排序会完全失效因为10M在字典序上会比2G“大”这显然不对。因此我们必须掌握sort的高级用法才能正确理解空间分布。3.1 应对“人类可读大小”排序的关键选项-h(human-numeric-sort)核心中的核心这是让sort能正确理解du -h输出的2K,150M,1.2G这类带单位大小的关键选项。它会智能地解析这些字符串将其转换为统一的数值进行比较从而实现从大到小或从小到大的正确排序。没有-h选项对du -h的输出进行排序是毫无意义的。-r(reverse)反转排序结果默认排序是升序从小到大。加上-r就变成降序从大到小。在分析磁盘空间时我们几乎总是想先看最大的那些所以-r和-h经常联用sort -hr。-n(numeric-sort) 与-h的区别这是一个常见的混淆点。-n是按数字排序但它要求字符串以数字开头。对于du不带-h的输出纯数字单位是KiB用-n排序是正确的。例如du -s输出1024和20480用sort -n能正确排序。但一旦用了-h输出变成1.0M和20M-n就无法解析了必须用-h。简单对比表场景du命令输出示例正确的sort选项错误选项及后果查看人类可读大小4.0K,1.2M,500Gsort -hr(降序)用sort -n会乱序因为500G开头是字母查看原始KiB大小4096,12582912sort -nr(降序)用sort -hr可能出错因为12582912没有单位3.2 进阶技巧多列排序与去重sort的功能远不止于此结合其他场景也能发挥巨大作用。-k(key)指定排序的列du -h的输出默认是“大小 路径名”。当你使用-a选项列出文件时或者用find结合du时路径名可能包含空格。sort默认以空白字符空格、制表符作为分隔符按第一列排序。但如果你想按第二列文件名的字母顺序排呢或者当输出格式变化时你需要指定按哪一列排序。du -ah . | sort -hr这是按第一列大小降序排最常用。du -ah . | sort -k2这是按第二列路径名的字典序升序排。-u(unique)去重有时du的扫描可能会因为软链接等原因导致路径重复计算虽然du默认会避免跟踪软链接。或者你从多个来源合并了列表可以用sort -u来去除重复行。注意它是在排序的基础上去重。一个综合例子分析日志目录按日期和大小排序假设你的应用日志按日期分割app-2023-10-01.log,app-2023-10-02.log… 你想找出最大的几个日志文件同时看看它们的日期。find /var/log/myapp -name app-*.log -exec du -h {} \; | sort -hr | head -5这条命令会找出/var/log/myapp下所有app-开头的日志文件计算大小然后按从大到小排序最后只显示前5个。结果一目了然你知道是哪几天的日志最“胖”。4. 黄金组合实战从基础排查到高级空间分析掌握了du和sort的各自本领后我们就可以将它们组合起来解决各种复杂的磁盘空间问题。下面我分享几个从简单到复杂从通用到特定场景的实战命令组合这些都是我多年运维工作中积累下来的“干货”。4.1 基础必备快速定位目录空间占用TOP榜这是最经典、使用频率最高的组合。无论你在哪个目录当你感觉空间紧张时首先应该运行它。命令sudo du -h -d 1 | sort -hr分解与解读sudo因为很多系统目录如/var,/usr需要root权限才能读取所有文件信息。在用户目录下可以不加。du -h -d 1以人类可读格式统计当前目录下所有一级子目录和文件的磁盘占用。注意-d 1在这里是关键它让我们聚焦于直接子项不会陷入过深的递归。|(管道)将du命令的输出作为sort命令的输入。sort -hr-h人类数字排序-r反转降序。这样最大的项就排在最前面。输出示例4.6G ./project_data 2.1G ./logs 780M ./cache 120M ./config 4.0K ./README.md一眼就能看出project_data目录是空间消耗的主力。接下来你就可以cd project_data然后再次运行du -h -d 1 | sort -hr进行下一层钻取。4.2 进阶搜索揪出隐藏的巨型文件有时候空间被一个巨大的文件占用了但这个文件可能藏在很深的目录层级里。用上面的方法一层层cd和du虽然有效但不够直接。我们可以用find命令来全域搜索大文件再结合du和sort来展示。命令1找出当前目录及子目录中最大的10个文件find . -type f -exec du -h {} 2/dev/null | sort -rh | head -n 10分解与解读find . -type f在当前目录.下查找类型为文件(f)的所有项。-exec du -h {} 对找到的每一个文件执行du -h命令来获取其大小。{}是占位符代表找到的文件名。表示将多个文件一次性传递给du命令效率比\;高。2/dev/null将错误信息如权限不足重定向到“黑洞”让输出更干净。注意这可能会隐藏一些重要错误在需要完整信息时可以去掉。sort -rh按大小降序排。head -n 10只显示前10行。命令2找出大于特定尺寸的文件例如大于100MBfind / -type f -size 100M -exec du -h {} \; 2/dev/null | sort -rh-size 100M查找大小超过100MB的文件。单位可以是k(KB),M(MB),G(GB)。这个命令从根目录/开始搜索范围广可能需要较长时间和root权限。建议在知道问题大概范围时将/替换为更具体的路径如/home或/var。4.3 特定场景清理日志、缓存与临时文件许多磁盘空间问题都源于日志、缓存和临时文件的无限制增长。下面是一些针对性的清理前分析命令。分析日志目录如/var/log# 查看各日志子目录大小 sudo du -h -d 1 /var/log | sort -hr # 查看最大的10个日志文件包括归档的.gz文件 sudo find /var/log -type f \( -name *.log -o -name *.gz \) -exec du -h {} | sort -rh | head -10分析用户缓存如~/.cache# 查看缓存目录下哪些软件缓存最大 du -h -d 1 ~/.cache | sort -hr # 常见的可清理目标浏览器缓存、软件包管理器缓存apt/yum/dnf、IDE缓存分析Docker磁盘占用如果使用了DockerDocker是个典型的空间消耗大户镜像、容器、卷都会占用大量空间。# 查看Docker总体磁盘使用 docker system df -v # 结合du查看Docker数据目录默认/var/lib/docker的详细分布 sudo du -h -d 2 /var/lib/docker | sort -hr | head -204.4 生成可视化报告给领导或自己一个清晰视图当你需要定期巡检服务器磁盘空间或者向团队报告存储使用情况时一个格式清晰的报告很有用。我们可以将命令输出重定向到文件并稍作格式化。生成一个简单的空间使用报告{ echo 服务器 $(hostname) 磁盘空间分析报告 echo 生成时间: $(date) echo echo 【根目录一级子目录大小排行】 sudo du -h -d 1 / | sort -hr echo echo 【/var目录详细分析】 sudo du -h -d 2 /var | sort -hr | head -15 echo echo 【大于1GB的文件列表】 sudo find / -type f -size 1G -exec du -h {} \; 2/dev/null | sort -rh } ~/disk_usage_report_$(date %Y%m%d).txt这个脚本会将分析结果保存到一个带有时间戳的文本文件中内容结构清晰包含了概况、重点目录分析和特大文件列表。5. 避坑指南与性能优化心得工具虽好但使用不当也会踩坑尤其是在生产环境执行时。下面是我总结的几个常见问题和优化技巧。5.1 权限不足与“拒绝访问”当你使用sudo du扫描系统目录时基本不会遇到问题。但在扫描像/home这样包含多个用户目录的地方时即使有sudodu也可能因为无法进入某些用户的.private目录或遇到特殊权限文件而报错。命令会继续执行但输出中会夹杂Permission denied的错误信息干扰阅读。解决方案忽略错误最常用将标准错误重定向到/dev/null。sudo du -h /home 2/dev/null | sort -hr这会让输出非常干净。但代价是你完全看不到任何错误包括那些可能提示你存在异常权限配置的错误。分离错误推荐将错误信息输出到另一个文件既保持主输出干净又保留了错误日志供排查。sudo du -h /home 2 /tmp/du_errors.log | sort -hr # 之后可以查看错误日志 cat /tmp/du_errors.log | head -205.2 扫描速度慢与系统负载在拥有海量小文件例如代码仓库、邮件存储、日志碎片的目录上运行du可能会非常慢并且导致磁盘I/O升高在繁忙的生产服务器上需要谨慎。优化策略明确目标限定范围不要动不动就sudo du -sh /。先通过df -h命令看哪个挂载点空间紧张然后只针对那个挂载点下的主要目录进行扫描。使用--time选项预估du命令本身没有进度条。但你可以先在一个子集上运行估算总时间。或者使用--time选项让它显示每个目录的耗时帮你识别出扫描特别慢的“瓶颈”目录。考虑文件系统特性对于某些现代文件系统如ZFS, Btrfs它们可能提供更快的空间使用查询命令如zfs list。du是通用工具但在特定文件系统上未必是最优解。避免在高峰时段操作如果非紧急将磁盘分析任务放在业务低峰期进行。5.3 符号链接软链接的陷阱du命令默认情况下不会跟踪符号链接symlink。它会统计符号链接文件本身的大小通常很小而不是它指向的目标文件或目录的大小。这可能导致你误判。例子$ ln -s /var/log/mysql ./mysql_log_link $ du -sh mysql_log_link 4.0K mysql_log_link # 这只是链接本身的大小 $ du -shL mysql_log_link 180M mysql_log_link # 这是跟踪链接后实际目标的大小关键选项-L(dereference)使用-L选项du会跟踪符号链接并统计其指向的真实目标的大小。在分析可能包含大量软链接的目录时例如某些软件安装目录要注意是否需要加上-L来获得真实的空间消耗。5.4 脚本化与自动化监控对于需要定期检查的服务器我们可以将这套组合拳写成脚本加入定时任务cron。一个简单的每日空间检查脚本示例 (check_disk_usage.sh)#!/bin/bash # 简单磁盘空间检查脚本 LOG_FILE/var/log/disk_check.log THRESHOLD80 # 使用率告警阈值单位% echo 磁盘检查报告 $(date) $LOG_FILE echo $LOG_FILE # 1. 使用df查看整体使用情况 echo 【整体磁盘使用率】 $LOG_FILE df -h | grep -E ^/dev/ | awk {print $1, $5, $6} | while read device usage mount; do usage_percent${usage%\%} if [ $usage_percent -gt $THRESHOLD ]; then echo 警告: $device 挂载于 $mount 使用率 ${usage}超过阈值 ${THRESHOLD}% $LOG_FILE # 2. 如果根分区超过阈值则分析大目录 if [ $mount / ]; then echo 开始分析根分区大目录... $LOG_FILE sudo du -h -d 2 / | sort -rh | head -10 $LOG_FILE 2/dev/null fi else echo 正常: $device 挂载于 $mount 使用率 ${usage} $LOG_FILE fi done echo $LOG_FILE然后通过crontab -e添加一行每天凌晨3点运行0 3 * * * /root/scripts/check_disk_usage.sh这样你每天只需要查看/var/log/disk_check.log文件就能对服务器的磁盘健康状况有一个清晰的了解并在问题发生前得到预警。du和sort的组合其精髓在于将复杂的空间分析问题分解为“测量”和“排序”两个简单的步骤。它不依赖于任何图形界面在所有的Linux发行版和远程SSH会话中都能稳定工作。从一次紧急的磁盘空间告警处理到日常的存储资源规划这套命令都是最可靠的工具。我个人的体会是花时间熟练掌握它们比盲目安装各种图形化监控工具更有效因为它给了你最深层的控制力和洞察力。下次当你再遇到“磁盘空间不足”的提示时希望你能自信地打开终端敲下du -h -d 1 | sort -hr开始你的排查之旅。
返回列表