Writing manual pages on Linux


It’s a very common fact that nobody likes to write documentation. Heck, nobody likes to read it either. But there are times when we have to read it in order to, say, finish the project on time, or, especially when working in software development, even write it. If you only have to read it, we always encouraged you to do so, but if you’ll have to write the manual pages and need a kickstart, here’s the article for you. If you worked previously with HTML your life will be easier, but if not it’s alright. Writing manual pages for Linux is not that hard, despite the look of the pages when read in plain-text. So basically you’ll need some Linux knowledge and the ability to use a text editor. You will learn (with examples, of course) the main concepts in text formatting as applied to man pages and how to write a simple manual page. Since we used yest as an example for our C development tutorial, we will use snippets from its manual page to illustrate our point during this article.

A little bit of history

The first manual packages written are said to be authored by Dennis Ritchie and Ken Thompson in 1971. The formatting software used was troff, and that format continues to be used to this day, although the tools may be different. The text formatting tool on Linux systems is now groff, with the leading ‘g’ coming from GNU. groff’s existence is owed to the fact that when troff was written, terminals meant something different in terms of capabilities than what they mean today. Another strong incentive for the GNU project to create groff was troff’s proprietary license. troff still lives on on other Unix systems, like OpenSolaris or Plan9, although under open source licenses.

Before we begin, we must tell you something about *roff: it’s typesetting software, like TeX for instance, and it’s a language in it’s own right. We won’t transform this article into a groff manual, nor will we make a list of differences between groff and troff. This is just a starter for simple manual page writing, and if you need more you will find lots of documentation on the Internet.


If after reading this you will feel that the syntax is daunting, we have a solution for your problem: pod2man. POD stands for Plain Old Documentation and offers a simpler syntax, and there is pod2man, which is a Perl module (part of perlpod) that translates documentation written in POD format to manpage format. perlpod also offers tools to convert POD to text or HTML, so just refer to your distribution’s documentation on how to install it.

Manual pages


Manual pages are divided into categories, depending on what subject they’re treating. They don’t differ on Linux distributions, but other Unix systems have different ways to divide manual pages. Using

 $ man man

will give you those categories and much more in regard to how to use the man command. The categories on Linux are as follows:

       1   Executable programs or shell commands
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]

You are advised to read the man manual page, because this is not a tutorial about how to use them, but how to write them.

Layout of a manual page

Since some years ago, there is a standard on how to write manual pages, what they should contain and style issues. They should be concise, respect the layout and compress as much information in as little space as possible. When one sees a 100-page manual, the first reflex will be to run away.

Far, far away. On the other hand, a short but informative manual page that will give the reader what he/she wants to know will be of real help, instead scaring/boring the user. If the program you’re writing manual pages for isn’t written by you (entirely), work with the developer(s) until you settle on how the manual should look like. Now, we want to avoid being boring or scary, let’s start with the layout.

First of all, the name of the file should be $commandname.$category, like, for example, vim.1. This file, when installed, should be gzipped and copied to the appropriate directory, which for vim should be /usr/share/man/man1. The non-compressed file is a plain text file, nothing more. Reading any manual page will give you an idea on how yours should look like:name, synopsis, description, options, examples, help, files, see also, author and bugs. Not all these are mandatory, but it’s recommended you provide them all should space suffice, for a better user experience.

The markup language

As stated earlier, if you’re used to writing XML or HTML, you’ll find the syntax simple. In fact, it’s simple anyway once you get used to it. We start with the heading, and the first heading is the title heading. The other usually encountered macros (the equivalent of tags in markup languages) are subject headings and paragraphs, but more on those later.

The title heading must contain the following: name, chapter (category) and the date the page was last modified. So, in order to get your feet wet, here’s how it should look:

.TH yest 1“19 Apr 2010”

TH stands for Title Heading, and as it’s a macro it must be dot-prefixed. yest is the name of the application, category 1, last edited on the 19th of April 2010. Before we go further, you might wanna insert some comments in your file before the title heading. These begin with .\” (dot backslash quote) and can look like this:

.\” Copyright 2004, 2006, 2010 Kimball Hawkins <khawkins@acm.org>.

.\” All rights reserved.

Now, insert these lines (the heading and the comment above it) and check the result with

 $ groff -man -Tascii yest.1

-Tascii instructs groff to output in ascii (text) format, but groff supports other types of output. We invite you to check out the groff manual page for that.

Next, now that we know how to deal with title headings, let’s go to the section headings. As you might have guessed, the macro is .SH and what it does is it introduces the name, synopsis, description, etc. sections as written above. So the syntax will be:

.SH NAME yest – date manipulation utility.

.SH SYNOPSIS .B yest\fR –help

.P .B yest\fR –license

.P .B yest\fR –version

.P .B yest \fR[\fB–idf=\fIstr\fR] [\fB–tz=\fItzone\fR] [[\fB\fR|\fB+\fR]\fIadjust\fR[\fBd\fR|\fBh\fR|\fBm\fR]] [\fIdate\fR] [\fIformat-string\fR] .

SH DESCRIPTION This is called “yest” because the default is to output yesterday\’s date. This utility knows about leap year, daylight savings time, and such variations. This utility adds or subtracts days, hours, and/or minutes from a given date, and outputs the results in the specified format. The default, if no adjustment is specified, is “-1d”

This is of course just a part of the manual, but let’s see what the new macros mean. .B stands for bold, and we recommend you paste this code in a file and test it as you go, with the groff command above. .P stands for paragraph, because as you can see, after each .P there is a double new line in the formatted page. The \f* ‘s are font change escape sequences, and what that means is that after the word “SYNOPSIS” .B tells groff to print in bold. However, after the word “yest” which is indeed printed in bold, we need “–help” to be printed with regular fonts, so this is what \fR stands for. Conversely, \fB stands for “print in bold” and it can be used interchangeably with .B . Using logic you can understand what \fl, for example, stands for.

Simple text, that is text that is not a heading or a section, is contained into paragraphs. A simple paragraph is delimited by a .PP macro, which creates a small vertical space between the actual paragraph and the next one. If you want a tagged paragraph, you can have it with .TP . Next we will talk about indentation.

Relative indentation means that the text is indented relative to the preceding and following text. To start a relatively-indented chunk of text, use .RS (Relative Start), and to end it use .RE (Relative End). Here’s an example:

.RS.7i If there are spaces or special characters in the string, it must be quoted. The program will recognize most \fBecho\fR-like escape conventions such as \\n” (newline) and \\t” (tab) in \fIformat-string\fR, and octal escapes (\\0nn) are supported.

.P If only a day adjustment is specified, the default \fIformat-string\fR is “%x”. If \fIadjustment\fR includes a time element, the default \fIformat-string\fR becomes “%x-%R”.


As you can see, you can have a .P macro inside a relatively indented piece of text. .P is just an alias for .PP, so they can be used interchangeably. You may have noticed the “.7i” after .RS: that tells groff to indent with seven spaces the text inside.

Using tables is just as straightforward as using relative indenting: .TS and .TE. You can, as said earlier, modify one word or an entire paragraph (from a typographical point of view, that is) with macros. The three ways you can alter a character are, as everyone knows, Bold, Italic, and Roman. So, for example, .BI alters the text following it in that it will appear both bold and italic.


Please note that this may be enough to get you started, but it’s not complete. These are not all the macros, and if you switch to a BSD system you might find that they use mandoc instead of groff, so you’ll have to do some learning by yourself if you wanna become proficient. Next, please read a few manual pages to see the main conventions that must be respected, such as putting the optional arguments to your application (if that’s the case) in square brackets or using {} to show that at least one of the arguments inside the braces must be used. All in all, documenting your software, even if you aren’t compelled by your employer, is good for you and the users of your software. You will be regarded as a careful developer and the users can use your creation easier, knowing what they can and what they can’t do.

Comments and Discussions
Linux Forum