服务器磁盘报警 90%,挨个目录 ls -la 看着都不大,就是找不到空间被谁吃了——这是用错了工具:ls 根本不统计目录树的总占用。查文件和磁盘信息的这组命令,每个回答的问题不一样,对上号才查得动。

这是 Linux 命令系列的一篇,承接 Linux 常见命令与工具地图

ls:列目录内容,先看懂 -la 的每一列

ls 列出目录内容,默认不显示 . 开头的隐藏文件、不显示详情,只给一排文件名。日常几乎都是配着参数用:

1
2
3
4
5
6
7
8
9
10
11
12
ls -la
# -l:长格式,每个文件一行,显示权限、大小、时间等详情
# -a:包含隐藏文件(. 开头的)

ls -lah
# -h:把大小从字节数转成人类可读的 K/M/G

ls -lt
# -t:按修改时间排序,最新的在最上面——找"最近改过什么"最快的办法

ls -lS
# -S:按文件大小排序,最大的在最上面

ls -l 输出的每一列都有含义,以这行为例:

1
2
3
-rw-r--r--  1 baizhe staff  3833 Jul  7 01:20 _config.yml
# 权限 链接数 属主 属组 大小 修改时间 文件名
# 权限列的读法(rwx 和数字模式)见 chmod/chown 那篇文章

权限列的完整规则在 Linux 权限与属主管理:chmod、chown 里讲过,这里不重复。

tree:树状展示目录层级

tree 以树状缩进展示目录结构,比 ls -R(递归列出但没有层级视觉)直观得多。它不是系统自带命令,macOS 和很多精简系统默认没有,要先装(brew install tree / apt install tree):

1
2
3
4
5
tree -L 2
# -L:限制展示深度,这里只展开两层——项目大了不加这个会刷满整个终端

tree -d
# -d:只显示目录,不列文件,看结构骨架时更清爽

file:不看扩展名,判断文件真实类型

file 读取文件开头的魔数(magic number)来判断真实类型,完全不依赖扩展名——文件没有后缀、或者怀疑后缀是假的(比如伪装成 .jpg 的脚本)时用它:

1
2
3
4
5
6
7
8
9
file photo.jpg
# 输出:JPEG image data, ... 1920x1080 —— 连分辨率都能读出来

file /bin/ls
# 输出:Mach-O 64-bit executable(macOS)或 ELF 64-bit(Linux)
# 二进制可执行文件能识别出格式和 CPU 架构

file mystery_download
# 没有扩展名的文件也照样识别,判断"这下载下来的到底是什么"时最有用

stat:文件元信息与三个时间戳

stat 显示文件的完整元信息:大小、权限、inode、属主,以及三个容易搞混的时间戳。这三个时间戳的区别值得单独记住:

1
2
3
4
5
6
7
8
9
10
stat -x _config.yml       # macOS/BSD 要加 -x 才输出可读格式;Linux/GNU 直接 stat 即可

Size: 3833 FileType: Regular File
Mode: (0644/-rw-r--r--) Uid: (501/baizhe) Gid: (20/staff)
Access: Tue Jul 7 02:07:29 2026
Modify: Tue Jul 7 01:20:52 2026
Change: Tue Jul 7 01:20:52 2026
# Access(atime):文件内容最后一次被读取的时间
# Modify(mtime):文件内容最后一次被修改的时间——ls -l 显示的就是它
# Change(ctime):文件元信息最后一次变更的时间

最容易讲错的是 ctime:它不是”创建时间”(create),是”变更时间”(change)——指的是元信息的变更。给文件 chmod 改个权限,内容一个字节没动,mtime 不变,但 ctime 会更新。排查”文件内容没变但权限什么时候被人改过”,看的就是 ctime

注意 stat 是 BSD/GNU 差异比较大的命令:macOS 上直接 stat file 输出一行紧凑格式,要 -x 才有上面这种可读输出;Linux 上正相反,直接 stat file 就是完整格式。跨平台写脚本时别依赖它的输出格式。

du 和 df:一个查”谁占的”,一个查”还剩多少”

这两个命令名字长得像,回答的问题完全不同:df(disk free)查文件系统级别的使用率——“这块盘还剩多少”;du(disk usage)统计某个目录树的实际占用——“这个目录一共吃了多少”。磁盘满排查时两个要配合用:

1
2
3
4
5
6
7
8
9
10
11
12
df -h
# -h:人类可读单位;输出每个挂载点的总容量、已用、剩余、使用率
# 先用它确认到底是哪个分区满了

du -sh /var/log
# -s:只显示总和,不逐个列出子目录
# -h:人类可读单位
# 统计指定目录树的总占用

du -sh /var/* | sort -rh | head -10
# 磁盘满排查的经典组合:列出 /var 下每个子目录的占用,
# 按大小逆序排列取前 10,一眼看出谁是大头

一个偶尔会遇到的现象:du 把整个分区加起来的数字比 df 显示的已用空间小很多。常见原因是有文件已经被删除、但还有进程占着它的文件句柄——这种文件 du 扫不到(目录里已经没有它了),df 却依然把它算在已用空间里,重启对应进程空间才会真正释放。

组合实战:磁盘满了怎么一步步定位

1
2
3
4
5
6
7
8
9
10
11
12
df -h
# 第 1 步:确认是哪个分区满了,比如看到 / 用了 92%

du -sh /* 2>/dev/null | sort -rh | head -10
# 第 2 步:从根目录开始,看哪个顶层目录占用最大
# 2>/dev/null 忽略没权限读的目录的报错

du -sh /var/* 2>/dev/null | sort -rh | head -10
# 第 3 步:进入最大的目录继续下钻,一层层缩小范围

ls -laSh /var/log | head
# 第 4 步:定位到具体目录后,按大小排序找出最大的文件

从分区到目录再到具体文件,三四层下钻通常就能定位。日志文件撑满磁盘是最常见的答案,所以很多人直接从 du -sh /var/log 查起。

常用参数速查表

命令/参数 作用
ls -la 长格式列出全部文件(含隐藏)
ls -lt / ls -lS 按修改时间 / 按大小排序
tree -L N 树状展示目录,限制 N 层深度
tree -d 只显示目录
file 文件 按内容魔数判断文件真实类型
stat 文件 查看元信息;macOS 加 -x 才是可读格式
atime / mtime / ctime 最后访问 / 内容修改 / 元信息变更时间
df -h 各分区磁盘使用率
du -sh 目录 目录树总占用
du -sh /* | sort -rh 磁盘满排查:按占用从大到小排

写到这里

这组命令按问题分工:文件列表和排序找 ls,目录结构找 tree,文件类型找 file,元信息和时间戳找 stat,磁盘空间 df 定分区、du 定目录。磁盘报警时别再挨个 ls 了——dfdu 逐层下钻,几条命令就能揪出占空间的元凶。