如何在 Linux 上使用 ls 命令列出文件和目录

深入探索 Linux `ls` 命令的奥秘

我们每天都在不经意间使用 Linux 的 `ls` 命令,但或许我们错过了它所蕴藏的丰富功能。仔细研究 `ls`,你会发现它提供了许多实用的选项,其中一些绝对值得添加到你的命令行工具库中。

`ls`:文件和目录的列举

`ls` 命令对大多数 Linux 用户来说,可能都是接触到的第一个命令。我们这些经常在命令行工作的人几乎每天都会用到它,但却很少深入思考它。 这解释了为什么 `ls` 命令的功能比大多数用户所意识到的要多得多。 我们通常用它来列出文件,以查看目录的内容,或者使用长格式来查看文件的权限。 除此之外,我们很少会考虑它的其他用法。

`ls` 是一个功能极其丰富的命令。 或许这正是问题所在,因为选项太多,我们很难筛选出真正有用的。 即使找到了,又该如何记住它们呢?

事实上,`ls` 命令的各种组合形式,包括不同的选项和参数,是创建别名的理想选择。在大多数发行版中,我们认为的 “原始” `ls` 命令实际上已经是一个别名了。我们可以使用 `type` 命令来 查看别名的定义。下面我们来看看 `ls` 的定义:

输入 `type ls`

每次我们使用 `ls` 命令时,它会自动包含 `–color=auto` 参数。 这就是为什么列表中的不同文件类型会显示不同颜色的原因。

简单的 `ls` 列表

每个用过 Linux 终端的人都知道,默认情况下,`ls` 会列出当前目录中的所有文件和目录。

ls

如果你希望以单列形式显示列表,可以使用 `-1` 选项(每个文件占一行):

ls -1

我们稍后会讨论列表顶部的那个奇怪的文件名。

在不同的目录上使用 `ls`

如果想让 `ls` 列出其他目录中的文件,只需要将目录的路径作为参数传递给 `ls` 命令即可。 你也可以传递多个目录给 `ls`,让它依次列出这些目录的内容。 例如,我们可以让 `ls` 列出两个目录,分别是 “Help” 和 “gc_help”:

ls Help gc_help

当 `ls` 列出第一个目录的内容后,会继续列出第二个目录的内容, 并且在处理每个目录时会打印出该目录的名称:

使用文件模式

如果想有选择地列出文件,可以使用模式匹配。问号 `?` 代表任何单个字符,而星号 `*` 则代表任何字符串。 例如,要列出所有以 `ip_` 开头的文件或目录,可以使用以下命令:

ls ip_*

要列出所有以 `.c` 为扩展名的文件,可以使用以下命令:

ls *.c

你还可以将 `ls` 命令与 `grep` 命令结合使用,利用 `grep` 的模式匹配能力。 例如,我们可以查找所有文件名中包含 “_pin_” 字符串的文件:

ls | grep _pin_

这与单独使用 `ls` 配合两个通配符的效果几乎相同:

ls | grep _pin_
ls *_pin_*

为什么说是 “几乎” 相同呢? 注意它们输出的布局。`grep` 强制输出为每行一个文件名的格式。

非打印字符

你可能会遇到文件名中包含非打印或控制字符 的情况。 这种情况通常发生在你解压从网上下载的压缩包,或者检出 Git 仓库时,因为原作者在创建文件时犯了错误而没有发现。

我们之前提到的那个奇怪的文件就是这种情况:

如果我们在文件浏览器中查看并按 “F2” 重命名,非打印字符会显示为一个奇怪的符号。

我们可以使用 `-b`(转义)选项来查看文件名的实际内容。这个选项可以让 `ls` 使用 C 编程语言 的方式来表示控制字符。

ls -b a*

这个神秘的字符原来是一个换行符,在 C 语言中表示为 `\n`。

忽略文件

如果想从列表中排除某些文件,可以使用 `–hide` 选项。 假设你不想在列表中看到备份文件(`.bak` 文件),可以使用以下命令:

ls
ls --hide=*.bak

可以看到,第二个列表中已经不包含 `.bak` 文件了。

长格式列表

`-l` (长列表) 选项会让 `ls` 命令显示每个文件的详细信息。

ls -l

这里的信息量很大,我们逐一解释一下。

`ls` 首先会显示列表中所有文件的总大小。 然后,每个文件或目录会单独显示在一行上。

第一组十个字母和破折号代表文件类型以及所有者、所属组和其他用户的权限。

第一个字符代表文件类型,它的取值可能是以下几种:

  • `-` : 普通文件
  • `b` : 块特殊文件
  • `c` : 字符特殊文件
  • `d` : 目录
  • `l` : 符号链接
  • `n` : 网络文件
  • `p` : 命名管道
  • `s` : 套接字

接下来的九个字符是连续显示的三组三个字符。 每组三个字符依次表示读取、写入和执行权限。 如果授予了权限,则会显示 `r`、`w` 或 `x`;如果未授予,则显示连字符 `-`。

第一组三个字符代表文件所有者的权限, 第二组三个字符是文件所属组的权限, 最后一组三个字符是其他用户的权限。

有时,所有者的执行权限会用 `s` 表示。这代表 设置用户 ID (setuid)。 如果设置了 `setuid` 位,则意味着该文件会以文件所有者的权限执行,而不是执行该文件的用户的权限。

组的执行权限有时也会用 `s` 表示。这代表 设置组 ID (setgid)。 如果将 `setgid` 位应用于文件,意味着该文件会以文件所有组的权限执行。 如果将 `setgid` 位应用于目录,则在该目录中创建的任何文件都会从创建该文件的目录中获取其组权限,而不是从创建该文件的用户那里获取。

其他用户的执行权限有时会用 `t` 表示, 这代表 粘着位 (sticky bit)。 这个位通常应用于目录。如果设置了粘着位,那么只有文件的所有者、目录的所有者或者 root 用户才能重命名或删除目录中的文件,无论对目录中的文件设置了什么样的写入和执行权限。

粘着位的常见用法是在 `/tmp` 这样的文件夹上。 这是一个所有用户都可写的目录。 目录上的粘着位确保用户和用户启动的进程只能重命名或删除他们自己的临时文件。

我们可以在 `/tmp` 目录上看到粘着位的效果。 注意 `-d` (目录) 选项的使用。 这个选项可以让 `ls` 命令报告目录的详细信息。 如果没有这个选项,`ls` 将会报告目录中的文件。

ls -l -d /tmp

权限后面的数字代表文件或目录的硬链接数。 对于文件来说,这个数字通常是 1,但如果创建了其他的硬链接,这个数字就会增加。一个目录通常至少有两个硬链接:一个指向目录本身,另一个是它在父目录中的条目。

接下来显示的是文件所有者和所属组的名称。 之后是文件的大小和文件最后修改的日期, 最后是文件名。

人类可读的文件大小

以字节为单位显示的文件大小并不总是那么直观。 为了以更合适的单位(千字节、兆字节等)查看文件大小,可以使用 `-h`(人类可读)选项:

ls -l -h

显示隐藏文件

要查看隐藏文件,可以使用 `-a`(全部)选项:

ls -l -a

列表中的 `.` 和 `..` 分别代表当前目录和父目录。一个名为 `.base_settings` 的隐藏文件现在也显示出来了。

省略 `.` 和 `..` 条目

如果你不希望列表中包含 `.` 和 `..` 条目,但仍然想查看隐藏文件,可以使用 `-A`(几乎全部)选项:

ls -l -A

现在,隐藏文件仍然显示出来了,但是 `.` 和 `..` 条目已经被省略了。

递归列出目录

要让 `ls` 列出所有子目录中的文件,可以使用 `-R`(递归)选项:

ls -l -R

`ls` 会遍历起始目录下的整个目录树,并列出每个子目录中的文件。

显示 UID 和 GID

如果要显示用户 ID 和组 ID,而不是用户名和组名,可以使用 `-n`(数字 uid 和 gid)选项:

ls -n

对列表进行排序

你可以按照扩展名、文件大小或修改时间对列表进行排序。 这些选项不必与长列表格式一起使用,但通常结合使用会更有意义。 例如,如果按照文件大小进行排序,那么在列表中查看文件大小会很有用。当按照扩展名类型进行排序时,长列表格式则没有那么重要。

要按照扩展名排序,可以使用 `-X` (按扩展名排序) 选项。

ls -X -1

首先列出的是没有扩展名的目录,然后其余文件会按照扩展名的字母顺序进行排序。

要按文件大小排序,可以使用 `-S` (按文件大小排序) 选项。

ls -l -h -S

排序顺序是从大到小。

要按修改时间排序,可以使用 `-t` (按修改时间排序) 选项。

ls -l -t

列表会按照修改时间进行排序。

如果文件的修改时间在今年,则显示的信息为月份、日期和时间。 如果修改日期不在今年,则显示的信息为月份、日期和年份。

想要快速获取目录中最新和最旧的文件,可以将 `ls` 命令与 `head` 和 `tail` 命令结合使用。

要获取最新的文件或目录,可以使用以下命令:

ls -t | head -1

要获取最旧的文件或目录,可以使用以下命令:

ls -t | tail -1

反转排序顺序

要反转任何排序顺序,可以使用 `-r` (反转) 选项。

ls -l -h -S -r

现在列表会按照从小文件到大文件的顺序排列。

还有更多

仔细阅读 `ls` 的手册页,你会发现 还有更多的选项。其中一些选项可能只在特定的情况下使用,但偶尔你会庆幸自己了解它们。

如果你需要以 Linux 能够提供的最大精度查看文件的时间戳,可以使用 `–full-time` 选项:

ls --full-time

也许你想查看文件的 inode 编号? 使用 `-i` 选项:

ls -i

如果你使用的是单色显示器,并希望消除将目录和链接与文件混淆的所有风险,可以使用分类选项,`ls` 会将以下符号附加到每个列表条目中:

  • `/` : 目录
  • `@` : 符号链接
  • `|` : 命名管道
  • `=` : 套接字
  • `*` : 可执行文件
ls -F

深入挖掘,你会发现 `ls` 命令是一座宝藏,你会不断发现新的用法。