UNIX? 有成百上千条命令,不可能记住所有选项和细节。好在不需要这样:手册(UNIX 内置的联机参考系统)是用户最好的朋友。
可以在 UNIX 命令行上使用的命令有很多(粗略统计超过 1,500 个命令),每个命令具有许多特性,不可能记住每个选项、细节和排列次序。更糟糕的是,经过 40 年的发展,UNIX 命令存在各种各样的差异。例如,-l
在 ls
命令中表示 “long 格式”,但是在其他与文件相关的命令中不是这个意思,甚至根本没有这个选项。另外,一些命令行程序支持 –help
,这个选项输出简要的使用方法说明,但是并非所有命令都有这个选项。随着命令行越来越强大,学习的难度也相应地增加了。
与学习任何技能一样,随着时间的推移,经常使用的命令序列会被记住,成为本能。另外,根据您使用的 shell,可以为经常使用的命令行组合建立别名或 shell 脚本,这可以减轻记忆负担。一些 shell 还提供很长的命令历史,可以跨会话保存以前使用过的命令。
但是,记忆会模糊,还需要掌握新命令。要想真正掌握命令行,就必须利用手册。man 系统是 UNIX 内置的联机参考系统。实际上,对于那些最讨厌的问题,UNIX 社区的回答往往是 “RTFM!”,即 “去读手册页吧!”。
man 系统
UNIX 手册系统由两个部分组成:联机文档的集合和相应的文档阅读程序。每个文档称为一个手册页;根据主题不同,手册页的长度差异非常大。文档阅读程序仅仅是一个名为 man
的命令实用程序。
要想阅读系统上安装的软件的文档,只需输入 man component
,其中的 component 是软件的名称。例如,为了阅读 ls
实用程序的文档,输入:
$ man ls |
甚至可以阅读 man
本身的相关信息:
$ man man |
如果安装了 component
,它有手册页,应该会看到与 图 1 相似的屏幕(这里是 ls
的手册页)。如果指定的手册页不存在,man
就报告 No manual entry for component
。(除了指定名称之外,还有寻找手册页的其他方法,稍后介绍。)
图 1. 在终端窗口中运行的手册文档阅读程序
通常情况下,UNIX 系统上的所有软件(包括每个命令行实用程序、每个系统调用、编程库中每个可调用的函数和每种文件格式)都包含一个手册页。实际上,在构建新软件时编写并提供手册页被认为是一种必要的 “礼节”。
在以前,手册页存储库曾经放在 /usr/man。最近,存储位置已经改为 /usr/share/man,但是具体位置因 UNIX 版本而异。另外,软件包经常把它的手册页放在自己的根目录的子目录中。例如,MySQL 数据库引擎的一些版本把手册页存储在 /usr/local/mysql/man 中。这些策略都是允许的,但是,如果手册页分散在许多存储库中,就需要一些额外的配置。
无论它的位置在哪里,每个存储库都划分为一个或多个部分。每个部分实现为一个独立的子目录。每个部分按惯例命名为 man1、man2 直到 man8,分别包含一类命令的手册页。表 1 列出部分名及其内容。
表 1. 手册页存储库部分及其内容
部分 | 内容 |
---|---|
man1 | 一般命令。这个部分中的命令通常不需要超级用户(即管理员)特权。ls 、cat 和 passwd 放在这里,还有 shell。例如,请试试 man bash 。 |
man2 | 用来访问 UNIX 内核提供的服务的系统调用或函数。例如 fork 系统,它从一个现有的进程生成一个新进程。输入 man fork 显示它的手册页。使用系统软件的程序员常常参考这个部分。 |
man3 | C 库函数。许多软件包提供功能丰富的代码库,让开发人员可以创建新软件来补充现有的特性或开发全新的特性。每个库通常有一个手册页;一些库(比如系统的 libc)太大了,所以各个函数或一组相关函数有单独的文档。 |
man4 | 特殊文件,比如设备和驱动程序。 |
man5 | 文件格式。UNIX 几乎完全使用文本配置文件定制系统的操作。有大量配置文件,包括网络服务的列表 (/etc/services) 和可用的 shell 列表 (/etc/shells) 等等。 |
man6 | 游戏和屏幕保护程序。 |
man7 | 杂类文件。这是一个包罗万象的类别。在传统的系统上,可以了解 glob 操作符、正则表达式等方面的信息。 |
man8 | 系统管理命令,超级用户很可能要使用它们。 |
在某些情况下,不同部分中的组件可能名称相同。这种现象很常见,尤其是在一个软件包有多个部分的情况下。例如,第一部分中有 crontab
命令,它提交要调度的作业。同时,第五部分中有 crontab 文件格式,它描述要运行的作业。
为了区分不同部分中的同名组件,应该在第一个参数中提供部分号:
$ man 1 crontab |
前一个命令显示 crontab 命令的手册页;后一个命令显示 crontab 文件格式。如果一个软件在多个部分中存在,而您没有指定部分号,man
就会显示在编号最低的部分中找到的匹配。
手册页的内容
尽管各个命令的选项差异很大,但是手册页的内容相当有规律。实际上,手册页之所以是宝贵的参考资料,就是因为它们符合惯例。阅读一小段文字之后,您很快就能够跳到文档的正确部分,找到您要找的信息。
最简单的手册页包含五个部分:名称、大纲、描述、一些示例和其他相关资料的引用。在 图 1 中可以看到前三个部分。
- name(名称)给出命令、函数或文件格式的名称,以及对软件作用的单行的准确描述。
- synopsis(大纲)简要描述如何使用这个软件。如果手册页的主题是命令,那么这个部分显示必需的和可选的选项、参数的格式和参数次序。如果主题是系统调用或库函数,那么这个部分显示函数的形式参数以及使用函数所需的头文件(如果有的话)。
例如,下面是 BSD UNIX 上
du
命令的大纲。
du [-H | -L | -P] [-a | -s | -d depth] [-c] [-h | -k | -m | -g] [-x]
[-I mask] [file …]
命令大纲中使用的表示法是手册系统中有帮助的惯例之一(一些建模实用程序提供的使用方法提示借鉴了这种表示法)。这里的大纲的意思是,“输入
du
;可选地输入-H
、-L
或-P
选项之一;然后,可选地输入-a
、-s
或-d
之一,但是如果使用最后一个选项,还要指定一个深度(depth);指定-c
,也可以不指定;可选地输入-h
、-k
、-m
或-g
之一;指定-x
,也可以不指定;指定-I
和一个掩码,也可以不指定;最后,提供一个或多个文件名。省略号 (…
) 表示多于一个。
分组在一起的选项(比如第一组
-H
、-L
和-P
)的关系就像是图形用户界面 (GUI) 中的单选按钮:只能选择其中一个。独立的选项(比如-c
和-x
)就像是复选框:可以打开或关闭。这种表示法很容易阅读,很快就可以按照它输入命令。
下面是 BSD UNIX 上
open()
系统调用的大纲:
#include <fcntl.h>
int open(const char *path, int oflag, …);
这个大纲表明,需要头文件
fcntl.h
,open()
返回一个整数,必须指定要打开的文件的路径和一组决定模式(只读、读/写、打开并截断等等)的标志。
- description(描述)部分讨论特性、使用方法和命令行上可以使用的所有选项。如果想知道
du -H
的作用,可以阅读描述中的文本。
- examples(示例)部分给出实用程序的一般用途、常见的特殊情况和解释。
- 最后一部分 See Also(参见)提供相关资料的引用,比如其他相关命令、重要的系统文件、行业标准规范等等。
除了前面提到的几个部分,在手册页中可能还有其他特殊部分。一个重要的部分是 “Environment(环境)”。可以设置它列出的环境变量来影响实用程序的操作。例如,man
的手册页列出 10 个多环境变量,可以通过修改它们定制 man
。其中之一是 MANPATH,它指定寻找手册页时要搜索的目录。
手册页使用技巧
那么,如何高效地使用 man
?下面是一些有帮助的提示:
- 用 MANPATH 进行定制。shell 变量 PATH 指定在搜索可执行文件时要搜索的目录。例如,如果把 PATH 设置为 /usr/bin:/bin:/usr/local/bin,那么 shell 会依次在这三个目录中搜索命令行程序。同样,可以把 MANPATH 设置为冒号分隔的目录列表,
man
在这些目录中搜索手册页。例如,如果把 MANPATH 设置为 /usr/share/man:/usr/local/mysql/man(它们都是存储库的根目录),man
会在这两个目录中搜索匹配的手册页。
- 在手册页存储库中搜索内容。
man
实用程序可以在手册页中搜索字符串。例如,输入man -k pattern
寻找所有包含 pattern 的手册页。注意:这个操作可能非常慢。另一种方法是使用apropos
。它是man
的附件,它只搜索每个页面的单行 name 字段。它的搜索范围不如man -k
那么宽,但是非常快。
- 使用您喜欢的分页程序。
man
实用程序可以使用许多环境变量定制输出。通过设置环境变量 PAGER 使用您喜欢的分页应用程序,比如less
。一些系统提供手册页的 HTML 版本;在这些系统上,可以用 BROWSER 环境变量设置您喜欢的浏览器。
- 搜索内容。使用分页程序的搜索功能寻找需要的内容。例如,如果浏览 man 的手册页,使用的分页程序是
less
,希望了解 MANPATH 的相关信息,那么输入/MANPATH
(前向斜杠表示要搜索的命令),然后按回车。less
分页程序突出显示所有出现这个字符串的地方;可以分别使用n
和?
找到下一个和前一个出现这个字符串的地方。
- 消除干扰。使用 MANSECT 环境变量列出您希望搜索手册页的部分(即 1、2、3 直到 8)。没有出现在 MANSECT 中的部分都被忽略。例如,如果要忽略第一部分,只关注第五部分,那么把 MANSECT 设置为 5。
- 阅读手册页文件。如果您要编写新的手册页或已经从 Internet 下载了某些文件,可以使用
man
的直接模式阅读单一手册页。阅读特定手册页文件的方法是运行man filename
,其中的 filename 是文件的完全限定路径。例如,如果您正在编写 stocks.1(属于第一部分的一个新命令,用来显示股票报价),那么可以用man ./stocks.1
命令预览它。(如果忽略前面的路径,man
会在 MANPATH 指定的目录中搜索名为 stocks.1 的手册页。)
- 用
man
帮助您的同事。如果您在系统上安装了一批手册页,可以修改全局的 MANPATH,在其中包含新目录,这样就可以向使用系统的所有用户提供这些手册页。在文本文件 /etc/manpaths 中,每行列出一个存储库。还可以通过在 /etc/manpaths.d 目录中创建新的列表建立完整的子系统。输入man man.conf
可以找到更多信息。
顺便说一句,如果希望列出系统定义的系统范围的手册页存储库,只需输入 manpath
:
$ manpath |
但是,man
的一些版本会搜索超出 manpath
范围之外的目录。例如,在 BSD UNIX 上,man
还会搜索 PATH 中列出的每个目录和它们的父目录。因此,如果在 PATH 中包含 /usr/mysql/bin,man
会搜索这个目录和 /usr/mysql/man。
手册页,好帮手!
各个厂商提供的 UNIX 系统各不相同,所以您的手册页系统可能与这里介绍的特性不一样(更好或更糟糕)。但是,了解了手册页系统的缺点和优点之后,您可以顺利地适应这些差异。
一定要记住:阅读手册页。
关于作者
Martin Streicher 是一位 Ruby on Rails 的自由开发人员和 Linux Magazine 的前任主编。Martin 毕业于 Purdue University 并获得计算机科学理学硕士学位,从 1986 年起他一直从事 UNIX 类系统的编程工作。他喜欢收集艺术品和玩具。