
用了这么多年 Ubuntu真正让我意识到“命令行必须熟练”的时刻不是第一次装系统而是某天半夜收到线上服务器磁盘告警SSH 登上去手忙脚乱地敲df -h、du -sh一边心疼 IO 一边盯着屏幕找哪个目录在被日志塞爆。也是从那时起我才开始系统性地整理硬盘和内存相关的命令。这篇文章就聊聊我在 Ubuntu 上最常用的那些“查硬盘、查内存”的命令不是把手册翻给你看而是结合真实使用场景——什么时候该用哪个命令、输出怎么读、哪些参数是真的干活时会用到的、哪些又是纯属浪费记忆。如果你是刚入坑 Ubuntu 的开发者或运维新手这篇文章可以帮你省下很多到处搜索的时间。如果你已经用了一段时间但全靠free -m和df -h走天下那这篇文章也能帮你把工具链补齐至少在排查问题的时候不会大脑一片空白。核心就两个词硬盘、内存。围绕这两个主题我尽量说点文档里不会明说的实操细节。1. 硬盘篇先搞懂你手上有什么“盘”很多人一上来就敲df -h但说实话第一步应该是先搞清楚机器上到底挂了哪些存储设备。你以为是“硬盘满了”实际上可能是某个分区满了甚至是有块新盘根本没挂载。顺序错了后面的排查全都可能跑偏。1.1 用 lsblk 看清设备拓扑lsblk是我平时敲得最多的命令没有之一。它列出的是块设备block device的拓扑关系能看到磁盘、分区、LVM、RAID 等层次输出比/proc/partitions直观太多。lsblk默认输出大概长这样NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 100G 0 disk ├─sda1 8:1 0 512M 0 part /boot/efi ├─sda2 8:2 0 99G 0 part /注意看 TYPE 列disk代表物理磁盘part是分区lvm是 LVM 逻辑卷rom是光驱。MOUNTPOINT 列告诉我们这块盘挂载在哪里空着就表示没有挂载。如果加了新硬盘但系统没识别到lsblk都看不到它那就先别折腾挂载的事先看硬件层面的问题。带参数时我常用这几个组合lsblk -f # 显示文件系统类型和 UUID lsblk -p # 显示完整设备路径 lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT # 自定义输出列lsblk -f特别有用因为建文件系统、配/etc/fstab自动挂载的时候UUID 是绕不开的。用-o自定义列可以少看到一堆无关信息尤其是服务器上十几块盘的时候默认输出看得人头大。1.2 用 df 看文件系统空间利用率df是 disk free 的缩写查的是“文件系统”层面的使用情况而不是“物理磁盘”的。这个区别很重要——同一个物理磁盘切了两个分区你df -h看到的是每个分区的独立使用量想当然地把它们加起来去对比物理盘容量算出来的数字就会对不上。日常用法df -h # 人类可读的单位显示 df -T # 同时显示文件系统类型 df -h /var/log # 指定目录所在文件系统的信息-h是最常用的参数不用解释。-T会多打一列 TYPE告诉你这个分区是 ext4、xfs 还是别的东西。排查问题的时候文件系统类型直接决定了你能用哪些修复命令比如 xfs 的修复工具和 ext4 就完全不是一回事。需要稍微留神的是 Use% 这一列。你以为 100% 就完了对 ext4 来说即使显示 100%root 用户通常还保留了 5% 的预留空间这是为了应对碎片整理和紧急恢复。但你拿df怎么看都看不出这 5%得用tune2fs -l查。这个细节在“磁盘满”报错却明明有空间的情况里非常关键后面常见问题部分再展开。1.3 用 du 精确定位“谁吃掉了空间”df只能告诉你哪个文件系统满了du才是定位“罪魁祸首”的工具。du 是 disk usage 的意思它会递归统计目录下的文件大小。最经典的一条du -sh /*这条命令会显示根目录下每个一级目录占用的总大小。逐级进入目录重复执行就能像剥洋葱一样找到占空间最大的目录。服务器上通常/var/log、/home、/tmp是重灾区。如果是容器或虚拟化环境还得额外注意镜像和容器数据目录。我平时更常用的组合du -sh /var/log/* du -h --max-depth1 /home | sort -rh--max-depth1告诉 du 只统计一层子目录配合sort -rh按大小倒序排列直接找到大头。sort -rh里的-h让 sort 也能理解 K、M、G 这种单位光靠sort -rn在单位不统一时会排错顺序这个坑我踩过。1.4 用 fdisk / parted / blkid 做磁盘分区与信息确认查看磁盘分区表我用得最多的是 fdisksudo fdisk -l它能列出所有磁盘的分区表比如有几块盘、每块盘几个分区、分区起始扇区和大小。注意直接跑fdisk -l不需要 sudo 也能看到部分信息但有些设备会因为权限问题不完整建议直接加 sudo省得看到一个残缺列表然后一头雾水。新盘要分区的时候会进交互界面sudo fdisk /dev/sdb输入m看帮助n新建分区w写入退出。这套交互不太直观刚用的时候容易迷糊但胜在几乎所有 Linux 发行版都有属于保底技能。如果你更习惯图形化或更简单的交互可以装gdisk来处理 GPT 分区表或者用parted的命令行模式sudo parted /dev/sdb mklabel gpt sudo parted /dev/sdb mkpart primary ext4 1MiB 100%parted的优势是非交互式执行脚本友好。给一台机器批量分区时parted比 fdisk 容易自动化得多。blkid 用来查块设备的 UUID 和文件系统类型sudo blkid修改/etc/fstab实现开机自动挂载时blkid 给出的 UUID 就是我们需要填进去的值。手写设备名比如/dev/sdb1不是不行但设备名在重启后可能变化UUID 反而稳定得多。2. 内存篇free 只是起点别再只盯着 free 那一行内存这块的命令很多人就只会一个free -m然后看 total/used/free 三个数。这个习惯本身没大问题但你会漏掉很多关键信息尤其在遇到内存问题的时候。2.1 free 详解看懂 buffer/cache 和 available先给free -h的一个典型输出total used free shared buff/cache available Mem: 7.6Gi 2.1Gi 1.2Gi 12Mi 4.2Gi 5.0Gi Swap: 2.0Gi 0B 2.0Gi核心是不要被free列为 1.2G 吓到真正该看的是available这一列。为什么因为 Linux 会尽量把空闲内存用作 page cache页缓存这部分在内核看来是“已用”但应用程序需要内存时内核会立即回收。所以buff/cache占用高不一定是坏事反而说明内存没有浪费。available估算的是“在不触发明显 swap 的情况下还能给新进程多少内存”比free列靠谱得多。如果需要更细粒度的内存信息可以读/proc/meminfocat /proc/meminfo里面每一行的含义很多都能在free的 man page 里找到对应关系。但要说排查内存问题free的输出基本够了/proc/meminfo更多是给写监控脚本的人看的。再补一个参数free -s 3可以每 3 秒刷新一次有点实时监控的意思。不过别拿它替代 top因为 free 只看系统整体看不了进程级的内存占用。2.2 top / htop进程级内存排名与交互操作要说“到底哪个进程把内存吃满了”必须上toptop进来之后按M键按内存排序按P键按 CPU 排序按q退出。shift M或shift P也行大写键就是方便。这些快捷键是 top 里最高频的操作记不住别的可以这三个必须记住。top 默认每 3 秒刷新一次按e可以切换内存显示单位 KiB - MiB - GiB 旧版本叫法不太一样但基本都有。RES 列是进程实际驻留的物理内存大小VIRT 是虚拟内存大小两个数差距大很正常不要看到 VIRT 十几 GB 就以为内存要爆了。真正贴近物理内存占用的是 RES如果还想排除共享库的影响可以看代码段和数据段这就要用到后面的 smem。htop 是 top 的增强版Ubuntu 上需要先装sudo apt install htophtop 的优势是彩色显示、可以鼠标操作、树状视图方便看父子进程关系、F6 排序也很顺手。不过在一些精简服务器环境里可能没有 htop而 top 是必定存在的所以我的建议是两个都要会用如果只能选一个保底练熟 top。2.3 用 ps 和 smem 看更精确的内存占用ps 查进程内存也是老手段了ps aux --sort-%mem按内存占用排序直接看%MEM和 RSS 列。RSS 就是驻留内存集大小单位是 KB换成 GB 自己心算一下。这个命令适合快速定位“谁是内存大户”。但 RSS 有个缺陷——它会把共享内存库重复计入每个进程。两个进程共用同一个动态链接库RSS 会把库的大小各算一遍总和就会虚高。这时候smem就派上用场了。它统计的是 PSS比例集大小把共享库按进程数量分摊看起来更接近真实物理内存占用sudo apt install smem smem -s rss # 按 RSS 排序 smem -s pss # 按 PSS 排序 smem -k -s pss # 人类可读单位个人体会排查容器或 Java 应用的“内存到底吃在哪儿”smem 比 ps 和 top 都更能说明问题。3. 实战一磁盘空间告警的完整排查流程光会敲单个命令还不够真实场景里往往要把命令串起来用。我分享一个我自己总结的排查流程遇到“磁盘满告警”基本上可以一路顺着查下去。3.1 先看整体再定方向第一步永远是df -h这时候要快速判断是某个分区满了还是所有分区都吃紧如果是所有分区那大概率是某个服务在疯狂写数据方向比较单一。如果是单个分区满比如只有/满了/data还有很多空间那就是应用数据写到根分区了要么调整路径要么迁移数据。3.2 按目录逐层下挖锁定大头第二步du -xh --max-depth1 / 2/dev/null | sort -rh | head -20-x参数很重要它让 du 只在同一个文件系统内遍历不会跑到挂载点下面的其他分区去这样统计口径干净。2/dev/null是屏蔽权限不足的报错否则一堆 “Permission denied” 的噪音会淹没真正有用的输出。看到某个目录异常大之后继续du -xh --max-depth1 /var 2/dev/null | sort -rh | head -20重复这个过程直到定位到具体的子目录或文件。3.3 别忘了“已删除但未释放”的文件这个场景很反直觉df显示磁盘满但du把所有目录加起来后发现根本没占那么多。此时十有八九是有进程打开了某个已删除的大文件文件句柄没释放空间一直被占用。用这个命令揪出来lsof L1它会列出所有被删除但仍被进程打开的文件。看到结果后重启对应进程或服务空间就会真正释放。这个坑我在日志切割场景里踩过无数次logrotate 明明转了日志但进程不重新打开文件句柄磁盘空间只会越来越小。3.4 inode 耗尽也是一个隐藏雷还有一种“磁盘没满但写不进去”的情况是 inode 耗尽了。inode 是文件系统用来保存文件元数据的数据结构每个文件或目录都占一个。文件特别多但每个都很小比如大量缓存文件、邮件队列就可能把 inode 吃光。df -i看 IUse% 这一列。如果接近 100%即使df -h显示还有几十 GB 空间你也创建不了新文件了。解决思路基本是删除大量小文件或者把数据迁移到其他文件系统根治的话要考虑换用 inode 数量更合理的文件系统或调整格式化参数。4. 实战二内存告警/异常的排查思路内存问题比磁盘问题更隐蔽因为它涉及缓存回收、swap、进程生命周期等多个因素。下面是我的一套排查顺序。4.1 先看可用内存与 swap 使用free -h优先看 available如果 available 已经很低比如只有几百 MB再看 swap。swap 如果开始高强度使用说明物理内存确实吃紧了系统正在靠交换分区硬撑。长期高 swap 会严重影响性能因为磁盘 IO 比内存慢几个数量级。此时配合vmstat可以看 swap 的实时变化vmstat 1 10重点关注siswap in和soswap out两列。如果持续不为 0说明系统真的在频繁换页已经到了危险的边缘。4.2 按内存排序定位进程top进去按 M然后看 RES 最高的几个进程。常见的大户Java 应用JVM 堆、数据库、搜索引擎、浏览器桌面场景下多标签页都是内存怪兽。如果是 Java 应用光看 RSS 还不够可能还要进 JVM 层面看堆内外内存jcmd pid GC.heap_info不过这就属于另一个话题了Ubuntu 系统层面能确定“确实是这个进程吃内存”就够了。4.3 用 perf 或 systemd-analyze 查根因遇到偶发性内存告警但当前内存又没异常可以看一下历史信息。systemd系统下的服务有内存统计systemd-cgtop这个命令按 control group 显示资源占用对 systemd 管理的服务很有用能看出某个服务累计吃掉了多少内存。另外systemd-analyze blame可以用来查看系统启动时各服务的耗时虽然是查启动速度的但如果某个服务在启动阶段就消耗大量内存会间接导致后续进程创建时的内存压力。4.4 OOM 事件怎么查如果系统曾经发生过 OOM内存耗尽而杀死进程日志是必须看的journalctl -k | grep -i oom或查/var/log/syslog里的相关记录。输出会显示 OOM killer 选中的进程、当时的内存状态、触发顺序。看到记录之后就能针对性优化加大内存、给特定服务限制内存、调整 OOM 策略而不是傻傻地重启机器。5. 常见问题与避坑速查表前面讲了很多“怎么做”这里把高频问题和容易踩的坑汇总成表格省得你翻来覆去试。问题可能的根因排查命令有效对策df 显示已满但 du 统计空间对不上有进程占用已删除的大文件lsof L1重启或重启占用进程释放句柄df -h 有空余但文件创建失败inode 耗尽df -i删除大量小文件或用 find 批量清理free 显示 used 很高但系统流畅buff/cache 被当成已用内存free -h 看 available通常不需要处理缓存可回收swap 一直很高物理内存不足vmstat 1 10优化进程内存增加物理内存进程被莫名杀掉OOM killer 触发journalctl -k | grep -i oom限制进程内存优化配置加内存top 里看不到内存总况只看单一进程视图top 按 M 键排序后看头部调整视图头部行有全局内存总线另外有几个“经验型”的提醒命令输出里的单位别认错free默认单位几 KB 也好 MB 也好加-h最稳du统计大目录很慢很正常不要以为卡死了就 CtrlC可以加参数跳过某些目录lsblk看不到盘不代表盘没插上有时候是驱动问题要dmesg | tail看内核日志。还有一个冷门技巧查目录下到底有哪些大文件一条命令搞定find / -xdev -type f -size 100M -exec ls -lh {} \; 2/dev/null | sort -k5 -rh | head这条命令查找根文件系统下所有超过 100MB 的文件并按大小排序。适合日志目录特别深、用 du 一层层找很烦的情况。6. 几个容易被忽略但极好用的补充工具最后这部分聊聊一些“不常用但关键时刻救命”的工具。6.1 iostat 看真实磁盘 IO装了 sysstat 之后可以用sudo apt install sysstat iostat -x 3-x显示扩展统计3是每 3 秒刷新一次。这里能看出来磁盘的真正瓶颈到底在 IOPS 还是吞吐量还是负载。%util接近 100% 说明磁盘可能满负荷了但要注意SSD 和机械盘对%util的解读不完全一样SSD 本身并发能力强util 高可能只是瞬时请求多不一定代表打满。6.2 tuned 或 sysctl 调整内存与交换倾向Ubuntu 的默认内存策略比较中庸但某些场景下值得调一下vm.swappinesssysctl vm.swappiness这个值默认通常是 60意思是系统在内存压力下比较愿意使用 swap。对于个人桌面我一般调到 10 左右让系统尽量留在物理内存里应用响应更跟手。对于服务器我反而不建议随意调除非你已经对自己的工作负载很了解。修改方式sudo sysctl -w vm.swappiness10持久化还要写进/etc/sysctl.conf或/etc/sysctl.d/下的配置文件里。这个改动影响很微妙别指望它是万能优化但桌面体验确实能感觉到差异。6.3 用 watch 组合命令做持续观察排查问题不是每个命令跑一次就完了很多时候需要持续观察。watch可以定时执行命令并刷新屏幕watch -n 3 df -h watch -n 5 free -h用引号把复合命令包起来就能持续监控。我做压力测试或者观察脚本执行对系统的影响时经常开好几个终端窗口每个窗口watch一个命令。7. 结尾多说几句真心话写到最后说点个人长时间用下来的感受。很多人喜欢收藏一堆看起来高大上的命令但我看下来真正高频、真正救命的其实就集中在lsblk、df、du、free、top、ps、lsof这几个上。与其贪多不如把每个命令的常用参数练到条件反射。比如我提到过无数次lsof L1平时你可能用不上可一旦遇到磁盘空间神秘消失它就是唯一的排查入口这种“一次救命”的命令值得你多敲几遍记住它。另外数据无价。不管命令多熟练动分区、删文件、改 fstab 之前先确认你备份了该备份的东西。尤其用了rm就不用多说了一个回车下去往往没有后悔药可吃。如果你看完这篇能少搜几次命令、少踩几个深坑那就是它最大的价值了。希望你在 Ubuntu 上排查硬盘和内存问题的时候不再是只会 df 和 free 的状态而是能按照一套清晰的流程把问题定位到底。