man pages 创建

因为最近要搭建一个项目框架,所以这段时间都在研究一些相关的技术。比如怎么安排项目目录、怎么选 LICENSE、怎么用 Makefile 搞构建啊等等。今天就轻松一下,来看看 man 手册这个东西。看要怎么给自己的程序搞一个 man 手册,然后怎用 Makefile 安装上去。

1 概述

当我们在使用类 unix 系统遇到一个新的命令的时候,我们想要知道这个命令是用来干嘛的,支持什么选项,我们通常有两种做法:使用--help选项或者使用man命令(扩展:info 命令)。使用--help选项时,通常是由这个命令打印出一串帮助信息;使用man命令时,会去特定目录下寻找对应的 man 文件。现在我们想要做的就是为自己的程序创建一个 man 文件,并且安装到特定目录下。

1.1 troff

在添加一个 man 文件之前,首先要了解一下 man 文件是如何编排的。以GNU hello项目下的 man 为例,文件为hello.1:

1
2
$ file hello.1
hello.1: troff or preprocessor input, ASCII text

使用 file 命令查看hello.1,发现其为 ascii text 文件,但是写着是 troff 或者预处理输入。

这个 troff 是什么呢?

它其实源自一个古老的排版程序,期间经过多次变化,历史比较复杂,有兴趣的小伙伴可以去 wiki 看看。它本质上是一个排版程序,但是你可以把它看作一种文本格式(但其实不是),类似于 markdown。在编写可被 troff 解析的文件时,也可以使用.SH .B .TP等字符串来定义文本格式,这类似于 markdown 的各种标签。

.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.46.4.
.TH HELLO "1" "November 2014" "hello 2.10" "User Commands"
.SH NAME
hello - friendly greeting program
.SH SYNOPSIS
.B hello
[\fI\,OPTION\/\fR]...
.SH DESCRIPTION
Print a friendly, customizable greeting.

GNU 重写了一个 GNU troff(Groff),但是其本质都是一个排版程序。使用groff指令来看看排版后的hello.1文件:

1
$ groff -Tascii -man hello.1 | more

-man 告诉 groff 使用预定义好的 man 手册宏(即定义好的针对 man 手册的规则)集合,具体的groff的使用方法自己去man一下吧。

可以看到打印出了和我们直接使用man命令相同的内容

1
$ man ./hello.1

1.2 help2man

那么我们想要自制一个 man 手册又要学一种文本格式了吗?不用!做为一个懒惰的程序员,可以直接用 GNU 为我们准备好的help2man命令。使用这个命令可以给你的程序生成一个 man 手册,但是作为前提,你的程序必须提供两个选项:”–help“和”–version“。事实上,help2man就是使用这两个选项来生成 man 手册的。

详细的内容以及对”–help“和”–version“的要求去看 GNU 官网吧: https://www.gnu.org/software/help2man/ 。我懒得复制粘贴了:)。

简单的用法如下:

1
$ help2man ./hello -o hello.1

或者想在 Makefile 里使用,automake 提供了$(HELP2MAN) 宏:

1
2
3
4
hello.1: hello
	$(HELP2MAN) --include=$(top_srcdir)/man/hello.x $(top_builddir)/hello -o $@-t
	chmod a=r $@-t
	mv -f $@-t $@

3 安装 man 文件

通过help2man或者傻乎乎地自己写,我们得到了一个 man 手册文件。我们可以像 1.1 节里面提到的一样,直接对 man 文件使用groff或者man命令查看。但是要怎么样才能够达到像man ls这样直接对程序使用获得使用手册的效果呢。

3.1 man 手册安装位置

man 手册都被安装到哪里了呢?你可以查看 GNU hello 项目中的 Makefile 文件,看它是怎么处理的,或者直接使用man命令”-w“选项

1
2
$ man -w ls
/usr/share/man/man1/ls.1.gz

这个/usr/share/man/目录下保存的就是所有 man 手册了。

1
$ tree -d /usr/share/man

cs、zh_CN、zh_TW 之类的好理解,就是不同的语言。下面解释一下 man1~man8 是什么意思。

在 man 里,将不同类型的手册进行了分类,当 man 程序去查找手册时,会查找对应类别的目录。由 1~8:

1
2
3
4
5
6
7
8
9
   1   Executable programs or shell commandsplainplainplainplainplainplainplainplainplainplainplainplainplainplainplain
   2   System calls (functions provided by the kernel)
   3   Library calls (functions within program libraries)
   4   Special files (usually found in /dev)
   5   File formats and conventions eg /etc/passwd
   6   Games
   7   Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)
   8   System administration commands (usually only for root)
   9   Kernel routines [Non standard] 详细信息可以 man man。

按照分类 GNU hello 程序属于 1 类,因此 man 手册命名为 hello.1。安装到/usr/share/man/man1或者/usr/local/share/man/man1目录下。接着就可以使用man命令查看手册了。

扩展(Texinfo)

man ./hello.1最后一节中有这样一段话:

SEE ALSO
       The full documentation for hello is maintained as a Texinfo manual.  If the info and hello programs are properly installed at your site, the command

              info hello

       should give you access to the complete manual.

它让我们使用info命令查看 Texinfo 手册,这又是什么东西呢?我查了一番资料之后发现,原来 Texinfo 是 GNU 提出的一种新的标准手册格式,这种格式支持超链接,不过并没有多少人使用它。