Linux 中 ls 命令详解:列出文件、目录与权限、排序递归等用法

在 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 配合来检查和调整文件权限。