
在 Linux 终端中工作时,你经常需要查看某个目录里有什么内容,或者检查文件的权限和归属。ls 命令负责这些日常任务,它也可以显示隐藏文件、对条目排序,以及递归遍历子目录。
本指南通过实用示例讲解如何使用 ls 命令,包括日常工作中最常用的选项。
如何使用 ls 命令
ls 命令的语法如下:
ls [OPTIONS] [FILES]
不带任何选项或参数使用时,ls 会显示当前工作目录中所有非隐藏文件的名称列表,并以多列形式排布:
ls
文件按名称排序,并尽可能多地排成若干列以铺满终端宽度:
cache db empty games lib local lock log mail opt run spool tmp
要列出某个特定目录中的文件,把目录路径作为参数传入即可。例如,以下命令列出 /etc 目录的内容:
ls /etc
你也可以传入多个用空格分隔的目录和文件:
ls /etc /var /etc/passwd
如果你当前登录的用户对该目录没有读取权限,会看到一条提示说 ls 无法打开该目录:
ls /root
ls: cannot open directory '/root': Permission denied
下面的小节将讲解最常用的选项。
理解 ls -al 与长格式
默认输出只显示文件和目录名称。当你还需要权限、归属、大小和修改时间时,使用 -l(小写 L):
ls -l /etc/hosts
-rw-r--r-- 1 root root 337 Oct 4 11:31 /etc/hosts
输出包含文件类型与权限、硬链接数量、所有者、所属组、大小、修改时间和文件名。
第一个字符标识文件类型。在本例中,- 表示普通文件。常见取值有:
- - 普通文件。
- b 块特殊文件(Block device)。
- c 字符特殊文件(Character device)。
- d 目录。
- l 符号链接。
- p FIFO 或命名管道。
- s 套接字(Socket)。
接下来九个字符分别显示所有者、所属组和其他人的权限。每组通常使用以下字符:
- r 读取文件的权限。
- w 写入文件的权限。
- x 执行文件的权限。
- - 未授予该权限。
在执行权限位上出现 s 或 S 表示设置了 set-user-ID 或 set-group-ID 位;在最后一位出现 t 或 T 表示粘滞位(sticky bit)。关于这些特殊权限的完整说明,请参阅 chmod 命令指南。
在示例中,rw-r--r-- 表示所有者可以读写该文件,而所属组和其他人只能读取。数字 1 是硬链接数量。两个 root 字段分别是所有者和所属组,其后是文件大小(字节数)。
加上 -h 可以以 K、M、G 等单位显示较大的大小:
ls -lh /usr/bin/bash
-rwxr-xr-x 1 root root 1.3M Mar 31 2024 /usr/bin/bash
具体的文件大小和日期取决于你的系统。你可以用 chown 命令更改文件归属。
经常被搜索的 ls -al 命令结合了 -a 和 -l,以长格式显示隐藏条目:
ls -al
短选项的顺序可以任意,所以 ls -al 和 ls -la 产生相同的列表。
用 -a 和 -A 显示隐藏文件
默认情况下,ls 命令不会显示隐藏文件。在 Linux 中,隐藏文件是指任何以点(.)开头的文件。
要显示包括隐藏文件在内的所有文件,使用 -a。这里把它和 -l 组合,让隐藏条目也一并显示其权限和归属:
ls -la ~/
drwxr-x--- 10 linuxize linuxize 4096 Feb 12 16:28 . drwxr-xr-x 18 linuxize linuxize 4096 Dec 26 09:21 .. -rw------- 1 linuxize linuxize 1630 Nov 18 2017 .bash_history drwxr-xr-x 2 linuxize linuxize 4096 Jul 20 2018 bin drwxr-xr-x 2 linuxize linuxize 4096 Jul 20 2018 Desktop drwxr-xr-x 4 linuxize linuxize 4096 Dec 12 2017 .npm drwx------ 2 linuxize linuxize 4096 Mar 4 2018 .ssh
输出包含表示当前目录的 . 和表示其父目录的 ..。要显示隐藏文件但不包含这两个条目,使用 -A:
ls -lA ~/
列出目录自身信息(-d)
默认情况下,ls 列出目录的内容。要显示目录本身的信息而非其内容,使用 -d 选项。
当它与 -l 组合时最有用,可以在不查看目录内部所有内容的情况下检查目录的权限:
ls -ld /var/www
drwxr-xr-x 4 root root 4096 Jan 12 10:42 /var/www
追加类型指示符(-F)
-F 选项会在每个条目后面追加一个字符来指示其类型:
- / 目录。
- * 可执行文件。
- @ 符号链接。
- | FIFO。
- = 套接字。
要以类型指示符显示所有条目:
ls -F /etc/rc0.d
K01apache2@ K02cron@ README
这样无需使用完整长格式,就能一眼区分文件类型。
显示 inode、块大小与数字 ID
长格式始终打印相同的七列,但有几个选项会增加或删去一列。
使用 -i 可以在每个名称左侧打印 inode 号——文件系统用来标识文件的编号:
ls -li /etc/hosts
1835021 -rw-r--r-- 1 root root 337 Oct 4 11:31 /etc/hosts
同一文件系统上共享 inode 号的两个名称,是同一文件的硬链接,因此 -i 是确认这一点的快捷方式。
-s 选项打印文件在磁盘上实际占用的空间。文件系统以块为单位分配空间,所以这个数字通常比 -l 显示的字节数略大,对于稀疏文件则可能更小。加上 -h 可以以易读单位显示:
ls -sh /var/log/syslog
260K /var/log/syslog
其余选项会改变归属列中显示的名称:
- -n 长格式,但使用数字形式的用户和组 ID 而非名称。
- -o 长格式,省略所属组列。
- -g 长格式,省略所有者列。
- -Z 打印 SELinux 安全上下文;文件没有时打印 ?。
当你列出另一个系统(如挂载的磁盘或恢复的备份)上的文件时,使用 -n。文件存储的是数字形式的归属 ID,而 ls -l 会通过系统的账户数据库解析它们。同一个 ID 可能属于不同的本地账户,因此 -n 避免了这种歧义,并按存储原样显示数值:
ls -n /mnt/backup
-rw-r--r-- 1 1004 1004 2140 Feb 9 08:12 notes.txt
对 ls 输出排序
默认情况下,ls 按当前区域设置(locale)以名称的字母顺序排序。你可以用 --sort=name 显式请求按名称排序:
ls --sort=name
使用 -r 反转当前顺序:
ls -r
如果你需要可预测的、逐字节的排序顺序,而不是按区域设置感知的排序,为命令设置 LC_ALL=C:
LC_ALL=C ls
--sort 选项还支持按扩展名、大小、时间和版本排序:
- --sort=extension(或 -X)按扩展名字母顺序排序。
- --sort=size(或 -S)按文件大小排序,最大的在前。
- --sort=time(或 -t)按修改时间排序,最新的在前。
- --sort=version(或 -v)按版本号自然排序。
要把目录始终排在列表顶部,加上 --group-directories-first。它作为一个主排序键,因此目录和文件各自按其他选项设定的规则排序:
ls -l --group-directories-first
例如,以下命令按修改时间对 /var 排序并反转结果,把最旧的条目放在最前面:
ls -ltr /var
目录条目显示的大小并不是其内容的全部大小。要获取目录的大小,使用 du。
一个实用示例是查找最近修改的配置文件:
ls -lt /etc/*.conf | head
选择要显示的时间戳
三个标准文件时间戳分别是修改时间(mtime)、访问时间(atime)和状态更改时间(ctime)。mtime 在内容改变时更新,ctime 在写入以及权限或归属等元数据更新后更新。atime 记录文件访问,但 noatime 和 relatime 等挂载选项会影响它的更新时机。某些文件系统还会记录创建时间,通常称为诞生时间(birth time)。
在长格式中,ls 默认显示修改时间。当你加上 -t 时,它也以修改时间作为排序键。在长格式中使用 -u 可以改而显示访问时间:
ls -lu /etc/passwd
-rw-r--r-- 1 root root 2836 Sep 2 06:41 /etc/passwd
使用 -c 显示状态更改时间:
ls -lc /etc/passwd
这两个选项的作用不止于替换一列。当它们与 -t 组合时,还会改变排序键,因此 ls -ltu 按访问时间排序,而 ls -lu 仍按名称排序,只是显示访问时间。在没有长格式时,GNU 的 ls -u 和 ls -c 即使没有 -t 也会按所选时间戳排序。长格式写法 --time=atime 和 --time=ctime 作用相同。
在装有 GNU Coreutils 的系统上,--time=birth 会在文件系统提供时显示创建时间。如果没有可用的诞生时间,ls 会回退到修改时间:
ls -l --time=birth /etc/passwd
当想按创建时间排序时,把它和 -t 组合为 ls -lt --time=birth。
当缩写日期列精度不够时,加上 --time-style。long-iso 样式以可排序的日期时间(精确到分钟)打印:
ls -l --time-style=long-iso /etc/hosts
-rw-r--r-- 1 root root 337 2025-10-04 11:31 /etc/hosts
要获得系统能报告的最高精度,使用 --full-time,它是 -l --time-style=full-iso 的简写:
ls --full-time /etc/hosts
-rw-r--r-- 1 root root 337 2025-10-04 11:31:22.477817180 +0200 /etc/hosts
在调试构建系统时,纳秒时间戳值得了解,因为像 make 这样的工具比较的是完整时间戳,而不是默认显示的截断值。
递归列出子目录(-R)
-R 选项让 ls 命令递归显示子目录的内容:
ls -R
把递归与长格式和隐藏文件组合:
ls -lRa ~/Projects
递归输出是一系列扁平的、按目录分组的列表,而不是树状结构。当你需要带缩进的层级视图时,改用 tree 命令。
每行显示一个条目
-1 选项强制每行显示一个条目,让交互式输出更易于浏览:
ls -1 /etc
不要在脚本中解析 ls 的输出,因为文件名可能包含空格、换行符和其他特殊字符。要安全地处理任意文件名,请使用 find 的空字符分隔输出配合 xargs -0。例如,以下命令对当前目录中的每个普通文件运行 file:
find . -maxdepth 1 -type f -print0 | xargs -0 -r file
用 Shell 通配符过滤条目
要只包含匹配某个模式的名称,让 shell 展开该模式,并把得到的名称列表交给 ls。当你想从目录列表中排除匹配的名称时,GNU ls 还提供 --ignore=PATTERN 和 --hide=PATTERN。
要列出所有具有指定扩展名的文件,传入通配符模式:
ls -l *.log
? 字符精确匹配一个字符,常用于带编号或日期的文件:
ls -l backup?.tar.gz
方括号匹配集合中的任意单个字符,因此以下命令列出以 a 或 b 开头的配置文件:
ls -l [ab]*.conf
要只列出当前路径下的目录,把 -d 与以斜杠结尾的模式组合:
ls -d */
assets/ content/ layouts/ static/
由于展开由 shell 完成,ls 通常收到的是文件名而非模式本身。在 Bash 默认的通配符设置下,未匹配的模式会原样传递,ls 会把它作为缺失的文件报告:
ls: cannot access '*.log': No such file or directory
该消息表示没有文件匹配,而不是命令有问题。Bash 的 nullglob 和 failglob 选项会改变未匹配模式的行为。
常用 ls 命令示例
短选项可以在一个短横线后组合。以下示例涵盖你最可能用到的组合。
以可读大小的长格式显示隐藏文件:
ls -lah
按修改时间排序所有条目,最新者在前:
ls -lat
反转时间排序,显示最旧的条目在前:
ls -latr
按大小排序条目,最大的文件在前,并使用可读的大小单位:
ls -lhS
以长格式递归列出目录树:
ls -lR /var/log
故障排查
ls: cannot open directory: Permission denied(无法打开目录:权限不足) 你的用户无法读取该目录。用 ls -ld /path 检查目录自身的权限,如果该目录内容确实需要 root 访问权限,则使用 sudo 运行命令。
Argument list too long(参数列表过长) 一个通配符展开出的名称数量超过了内核在单行命令上允许的上限。改用 find,例如 find . -maxdepth 1 -name '*.log',它会自行读取目录条目,而不是把它们全部作为一次性参数接收。
Output has no colors(输出没有颜色) 颜色并非默认行为。大多数发行版通过一个 shell 别名(如 ls='ls --color=auto')启用,该别名在非交互式 shell 或全新安装的服务器上并不存在。显式传入 --color=auto,或者把这个别名加入你的 Bash 配置。避免在管道中使用 --color=always,因为它会嵌入转义序列,干扰接收命令。
「total 行与各文件大小对不上」:total 值统计的是已分配的磁盘块数,而不是字节数,并且只覆盖当前正在列出的目录。它不会与大小列的总和相符,也不是递归总计。需要目录树的真实大小时,请使用 du。
速查表
如需可打印的速查表,请参阅 ls 速查表。
| 选项 | 说明 |
|---|---|
| -l | 长格式,显示权限、所有者、大小和日期 |
| -a | 显示所有文件,包括隐藏文件(. 文件) |
| -A | 显示隐藏文件,但排除 . 和 .. |
| -h | 人类可读的大小(与 -l 一起使用) |
| -S | 按文件大小排序,最大的在前 |
| -t | 按修改时间排序,最新的在前 |
| -r | 反转排序顺序 |
| -R | 递归列出子目录 |
| -d | 显示目录信息而非内容 |
| -F | 给条目追加类型指示符(/、*、@) |
| -1 | 每行一个条目 |
| -X | 按文件扩展名字母顺序排序 |
| -v | 按版本号自然排序 |
| -i | 显示每个条目的 inode 号 |
| -s | 显示以块为单位分配的占用大小(与 -h 一起使用) |
| -n | 长格式,使用数字形式的 UID 和 GID |
| -o | 长格式,省略所属组列 |
| -g | 长格式,省略所有者列 |
| -Z | 显示 SELinux 安全上下文 |
| -u | 使用访问时间代替修改时间 |
| -c | 使用状态更改时间代替修改时间 |
| --time=birth | 文件系统支持时显示创建时间 |
| --time-style=long-iso | 以 YYYY-MM-DD HH:MM 格式打印时间戳 |
| --group-directories-first | 在文件之前列出目录 |
常见问题解答
ls -al 在 Linux 中是什么意思?ls -al 组合了 -a 和 -l。它以长格式显示隐藏文件(包括 . 和 ..),并附带权限、归属、大小和修改时间。
ls -a 和 ls -A 有什么区别?ls -a 显示所有条目,包括 . 和 ..。ls -A 显示隐藏文件但省略这两个特殊目录条目。
如何按日期列出文件,最新者在前?使用 ls -lt。加上 -r 反转顺序显示最旧者在前:ls -ltr。
如何让 ls 输出按名称的字母顺序排序?普通的 ls 会按你的区域设置以名称排序。使用 ls --sort=name 显式请求按名称排序,或者在需要可预测的逐字节顺序时使用 LC_ALL=C ls。
结语
ls 命令是 Linux 中最常用的命令之一,熟练掌握它的选项每天都能节省时间。把它和 find 配合使用来搜索和过滤,和 stat 配合来查看单个文件的全部细节,或者和 chmod 配合来检查和调整文件权限。