1 前言
在进入正题之前,先介绍一下“man page”这个术语。
维基百科上关于 man page 的解释:
man page(manual page 的缩写)是 Unix 和类 Unix 操作系统上的一种软件文档形式。涵盖的主题包括程序、系统库、系统调用,有时还包括本机系统详细信息。本地主机管理员可以创建和安装与特定主机有关的手册页。终端用户可以通过发出 man 命令并输入所需的特定详细信息来调用文档页。
简而言之,我们平时在各种 unix-like 系统上面敲 man 命令调出来的那些帮助文档,就是 man page。
不同操作系统的 man page,由各自的厂商或开源社区提供。比如 Linux 系统的 man page 是来自于这个项目:www.kernel.org/doc/man-pag…
本文主要介绍的就是这份 Linux 系统的 man page:Linux man pages。 (关于 page 的单复数形式,有些地方习惯写成单数形式,有些地方习惯写成复数形式。我这里跟随官方的项目名称,使用的是复数形式)
2 手册内容介绍
通常情况下,Linux man pages 拥有 8 个章节,它们的内容如下:
- General Commands Manual(常规命令手册)
- System Calls Manual(系统调用手册)
- Library Functions Manual(库函数手册)
- Kernel Interfaces Manual(内核接口手册)
- File Formats Manual(文件格式手册)
- Games Manual(游戏手册)
- Miscellaneous Information Manual(其他信息手册)
- System Manager's Manual(系统管理员手册)
我们常用的主要是前 3 个章节:
-
第 1 节:常规命令手册
介绍了用户命令和工具,例如文件操作工具、shell、编译器、web 浏览器、文件和图像查看器和编辑器等。
-
第 2 节:系统调用手册
介绍了 Linux 系统调用。系统调用是进入 Linux 内核的入口点。通常,系统调用不会被直接调用:相反,大多数系统调用都有相应的 C 库包装函数,这些函数执行调用系统调用所需的步骤(例如,陷入到内核模式)。因此,进行系统调用看起来与调用普通库函数相同。
-
第 3 节:库函数手册
介绍了除第 2 节中描述的实现系统调用的库函数(系统调用包装器)之外的所有库函数。本节中描述的许多函数都是标准 C 库(libc)的一部分。某些函数是其他库的一部分(例如,数学库 libm 或实时库 librt ),在这种情况下,手册页会写明链接这些库所需的链接器选项(例如,对于上述库,分别为 -lm 和 -lrt)。
3 使用方式
3.1 命令行
如果你给一台 PC 或者云服务器装了任意一个常见的 Linux 发行版,那么系统里面默认就会预置好 Linux man pages。什么都不用做,man 命令就是可以正常使用的。
最基础的使用,就是调用 man 命令的时候,把程序名字/syscall 名字/库函数名字作为参数。
比如,用 man 命令查看 ps 这个命令行工具的帮助文档
man ps
进入文档之后,可以按键盘上的 pageUp、pageDown 上下翻页,按 q 键退出。
3.2 在线文档
我们进入 “Linux man-pages”项目的主页:www.kernel.org/doc/man-pag…
可以在其导航栏上面看到有一个 “online pages”
点进去,就是 Linux man pages 的在线文档了,里面的内容跟 man 命令能查的内容是差不多一致的。
只能说差不多一致,而不是完全一致。因为机器上的 Linux man pages 是各大发行版的开源社区提供的,里面除了 Linux 社区的公共内容以外,可能还会额外包含各自发行版特有的一些信息。
此外,国内还有人做了 Linux man pages 的翻译。只是他们翻译的那个文档版本有点旧了,并且翻译完成度也不是很高,许多条目没有被翻译。感兴趣的话可以自己去 github 看看:github.com/man-pages-z…
4 常用操作
4.1 查系统自带命令
比如,用 man 命令查看 ps 这个命令行工具的帮助文档
man ps
你看到的 “PS” 就是帮助文档的名字(标题会自动显示全大写),“PS”的后面的“(1)”表示这个帮助文档在 Linux man pages 的第 1 节中
4.2 查第三方软件
我们不仅可以查到系统自带的命令行工具的帮助,甚至还可以查到一些第三方软件的帮助。
这是因为,在你安装第三方软件的时候,它们有可能会拷贝一些帮助文档到 /usr/share/man 目录下,这些文档最终就会体现在机器上的 Linux man pages 中。
比如这样
# 安装 clang 这个软件包
apt install clang
# 用 man 命令来查看 clang 的帮助文档
man clang
可以看到,CLANG 手册页也被调出来了,并且括号里面显示它是在 man page 第 1 节里面。
4.3 查 syscall
我们可以试试查一下第 2 节的内容,就查 openat 这个 syscall 吧
man openat
可以看到,OPEN 后面的括号里面是数字 2,说明它在 Linux man pages 第 2 节
如果你是第一次使用这个文档,阅读完文档全文,你可能就会产生一些疑问:
1. 为什么我查 openat,查出来的文档标题却是“OPEN”?文档里面还同时呈现了 open、creat、openat、openat2 这 4 个 syscall?
这是因为 Linux man pages 第 2 节并不会为每一个 syscall 都单独编写一个文档,它往往会把几个相关的 syscall 写在同一个文档中。所以你查这几个 syscall 查出来的都是同一个文档,它们都一起写在了 open 的文档中。
什么叫做“相关的 syscall”呢?按照我看到的规律,一般功能相近、代码实现在同一个文件中的 syscall 会被他们视为“相关的 syscall”,会被写在同一个帮助文档中。
比如上述这 4 个 syscall,它们都是实现在 Linux 内核代码的 open.c 这个文件中:git.kernel.org/pub/scm/Lin…
2. 为什么我查的是 syscall 文档,但文档里面却把库函数的函数签名和所在头文件也给呈现出来了?
查 syscall 文档,但文档里面却把库函数的函数签名和所在头文件也给呈现出来。这是 Linux man pages 故意这么设计的。
因为 libc 中几乎对所有的 syscall 都封装出了同名的库函数,为了方便开发者使用这些 syscall,他们在帮助文档里面直接就展示了这些“包装函数”了。
如果不使用这些库函数的话,我们要调用 syscall 会变得很麻烦,需要在 C 代码中以内联汇编的形式编写一些汇编代码,通过特殊的汇编指令陷入内核态完成 syscall 的调用。
4.4 查库函数
Linux man pages 第 3 节的内容是 libc 的库函数。
上面有提到,第 2 节也会展示库函数,那么第 3 节的库函数和第 2 节的库函数有什么区别呢?
区别:
- 第 2 节讲的都是 syscall 的“包装函数”
- 第 3 节讲的都不是 syscall 的“包装函数”。第 3 节的库函数,它们跟 syscall 并不是一一对应的关系。一个库函数可能会调用 0 个或多个 syscall,还有可能在 syscall 之上再做一层业务封装
比如 printf、sleep、fopen、exec 这些库函数都是第 3 节的内容
man printf
man sleep
man fopen
man exec
从括号后面的数字可以看出来,fopen 的文档在第 3 节中
4.5 指定章节查询
有些名字是会同时出现在多个章节中的。
比如 Linux 有个预置的命令行工具名字叫做 kill,而内核里面也有一个 syscall 名字叫做 kill。这种情况下第 1 节和第 3 节都会有关于 kill 的说明。
那么,我们要如何指定我们要查哪一节里面的 kill 呢?
只需要这样操作即可
# 在第 1 节查 kill,查到的是 kill 命令行工具的帮助文档
man 1 kill
# 在第 2 节查 kill,查到的是 kill syscall 的帮助文档
man 2 kill
4.6 查 man 命令的帮助文档
Linux man page 也对 man 命令的使用提供了帮助文档,所以你也可以用 man 命令去查它自身的帮助文档
man man
在这个文档中可以查阅到 man 命令的所有用法。