关于让 man 手册更清晰的笔记
大家好!在花了一些时间整理 Git 的 man 手册之后,我对什么样的 man 手册才算好有了更多思考。
我花了很多时间为一些以 man 手册为主要文档的工具(tcpdump、git、dig 等)编写速查表。这是因为我常常觉得 man 手册很难导航,很难快速找到想要的信息。
最近我一直在想——man 手册本身能不能就包含一份出色的速查表呢?怎样才能让 man 手册更易用?虽然我对此的思考还处于非常早期的阶段,但还是想先记下一些零散的想法。
我在 Mastodon 上询问了一些人最喜欢的 man 手册,下面是那些手册中让我觉得有意思的一些例子。
选项总览(OPTIONS SUMMARY)
如果你看过很多 man 手册,可能已经在 SYNOPSIS 中见过类似这样的内容:一旦要列出几乎整个字母表,就很难阅读
ls [-@ABCFGHILOPRSTUWabcdefghiklmnopqrstuvwxy1%,]
grep [-abcdDEFGHhIiJLlMmnOopqRSsUVvwXxZz]rsync 的 man 手册有一个我从未见过的解决办法:它把 SYNOPSIS 写得非常简洁,像这样:
Local:
rsync [OPTION...] SRC... [DEST]然后它有一个“OPTIONS SUMMARY”小节,用一行简介概括每个选项,像这样:
--verbose, -v increase verbosity
--info=FLAGS fine-grained informational verbosity
--debug=FLAGS fine-grained debug verbosity
--stderr=e|a|c change stderr output mode (default: errors)
--quiet, -q suppress non-error messages
--no-motd suppress daemon-mode MOTD之后才是常规的 OPTIONS 小节,对每个选项做完整说明。
按类别组织的 OPTIONS 小节
strace 的 man 手册不是按字母顺序,而是按类别(如“General”、“Startup”、“Tracing”以及“Filtering”、“Output Format”)来组织选项。
作为试验,我尝试把 grep 的 man 手册改成按类别分组的“OPTIONS SUMMARY”小节,你可以在这里查看结果。我还不确定怎么评价结果,但这是一次有趣的尝试。我在写的时候一直在想,自己怎么也记不住 grep 的 -l 选项叫什么。在 man 手册里找它总感觉要花很久,所以我在思考什么样的结构能让我更快找到它。也许按类别划分会更好?
速查表
有几个人向我推荐了 Perl 的整套 man 手册(perlfunc、perlre 等),我注意到其中有一个 man perlcheat,里面有像这样的速查表小节:
SYNTAX
foreach (LIST) { } for (a;b;c) { }
while (e) { } until (e) { }
if (e) { } elsif (e) { } else { }
unless (e) { } elsif (e) { } else { }
given (e) { when (e) {} default {} }我觉得这太棒了,不禁想,除了这种形式,是否还有其他方式能在 man 手册中用 80 字符宽的 ASCII 形式编写简洁的速查表。
示例非常受欢迎
一个常见的评论大致是“我喜欢任何带示例的 man 手册”。有人提到了 OpenBSD 的 man 手册,而 OpenBSD 的 tail 手册最后就包含了我常用的两种 tail 用法的示例。
我印象中 EXAMPLES 小节大多位于 man 手册的末尾,但有些手册(比如前面提到的 rsync 手册)会把示例放在开头。我在整理 git-add 和 git rebase 的手册时,也在开头放了一个简短示例。
目录与章节间链接
这并不是 man 手册本身的属性,但在终端里查看 man 手册时,很难一眼看出它有哪些小节。
在整理 Git 的 man 手册时,Marie(玛丽)和我做的一件事就是给托管在 Git 官网上的 man 手册 HTML 版本的侧边栏添加了目录。
我还想在某个时候给 Git man 手册的 HTML 版本添加更多超链接,这样你就可以点击“INCOMPATIBLE OPTIONS”直接跳到对应小节。在 Git 项目里添加这类链接非常容易,因为 Git 的 man 手册是用 AsciiDoc 生成的。
我觉得添加目录和内部超链接算是一种不错的折中:在不必维护一套完全不同的文档的前提下(至少在 man 手册的 HTML 版本上)对 man 手册的格式做一些改进。不过要实现这一点,你确实需要像 Git 的 AsciiDoc 系统那样搭建一套工具链。
如果能有一个通用的系统,让查找 man 手册中的某个具体选项(比如“-a 是干什么的?”)变得容易,那就太好了。我知道的最好技巧是在 man 分页器里搜索类似 ^ *-a 这样的模式,但我总是记不住去用,最后只好在手册里逐个翻查 -a 的出现位置,直到找到想要的内容。
为每个选项提供示例
curl 的 man 手册为每个选项都提供了示例,而且 HTML 版本还有目录,可以更方便地跳到感兴趣的选项。
例如,--cert 的示例让人一眼就能看出很可能还需要同时传入 --key 选项,像这样:
curl --cert certfile --key keyfile https://example.com他们的实现方式是为每个选项各写一个文件([每个选项一个文件](https://github.com/curl/curl/blob/dc08922a61efe546b318daf964514ffbf41583 25/docs/cmdline-opts/append.md)),文件里有一个“Example”字段。
用表格呈现数据
有不少人说 man ascii 是他们最喜欢的 man 手册,它看起来像这样:
Oct Dec Hex Char
───────────────────────────────────────────
000 0 00 NUL '\0' (null character)
001 1 01 SOH (start of heading)
002 2 02 STX (start of text)
003 3 03 ETX (end of text)
004 4 04 EOT (end of transmission)
005 5 05 ENQ (enquiry)
006 6 06 ACK (acknowledge)
007 7 07 BEL '\a' (bell)
010 8 08 BS '\b' (backspace)
011 9 09 HT '\t' (horizontal tab)
012 10 0A LF '\n' (new line) 显然 man ascii 是一个比较特殊的 man 手册,但我觉得它厉害的地方(除了随时能查 ASCII 对照表本身就很有用之外)在于表格形式让你很容易扫视并找到需要的信息。这让我想到,是否还有更多机会在 man 手册中用“表格”来展示信息,让查阅更高效。
GNU 的做法
聊到 man 手册时,经常会有人提到 GNU coreutils 的 man 手册(比如 man tail)没有示例,而 OpenBSD 的 man 手册则有示例。
我不想对此展开太多,因为这似乎是个相当有争议的话题,我在这里也无法讲清楚,但以下几点是我认为属实的:
- GNU 项目更倾向于用“info”手册来维护文档。这个页面说“man 手册已不再维护”。
- 阅读“info”手册有 3 种方式:查看其 HTML 版本、在 Emacs 中查看,或使用独立的
info工具。我听一些 Emacs 用户说他们喜欢 Emacs 里的 info 浏览器。我想我从未和任何使用独立info工具的人聊过。 - tail 的 info 手册条目在 man 手册底部有链接,它确实包含示例
- FSF 过去曾销售 GNU 软件手册的纸质书(也许现在有时仍在销售?)
当复杂度达到一定程度后,man 手册会变得非常难导航:虽然我从未用过 coreutils 的 info 手册,以后大概也不会用,但相比通过 man 手册,我几乎肯定更愿意通过 HTML 文档来查阅 GNU Bash 参考手册或The GNU C Library Reference Manual。
更多与 man 手册相关的内容
以下是一些我觉得有意思的工具:
- The fish shell 自带一个Python 脚本,可从 man 手册自动生成 Tab 补全
- tldr.sh 是一个由社区维护的示例数据库,例如你可以运行
tldr grep来查看。很多人告诉我觉得它很有用。 - Mac 上的文档浏览器 Dash 内置了一个不错的 man 手册查看器。我仍然在终端里使用 man 手册查看器,但我喜欢它包含了目录,效果如下:

在受限格式中思考很有意思
Man 手册是一种格式极其受限的文档,思考在如此有限的排版选项下还能做些什么,本身就很有趣。
尽管我非常喜欢写作,但我一直有个坏习惯,就是从不看文档,所以我很难判断自己到底觉得 man 手册里的哪些东西有用,我也不确定本文提到的大多数做法是否真的会改善我的体验。(除了示例,我超爱示例)
所以我很想听听你认为哪些 man 手册设计得很好、你喜欢它们哪一点,评论区在这里。
随机一篇博客