Writing Linux man pages & Keeping A Personal Collection of man pages ==================================================================== The master version of this file resides at /home/paulgorman/repo/man/README. A public copy resides at https://paulgorman.org/technical/linux-man-pages.txt. Linux man pages are produced by `groff`, a GNU clone of the venerable Unix typesetting system troff. Groff is a full-fledged typesetting system. Man pages use a particular set of groff macros, as described in groff_man(7). Groff instructions appear on their own line, beginning with a dot. Note that FreeBSD and OpenBSD have adopted a set of macros more semantically specific to man pages called "mdoc" or "mandoc". See groff_mdoc(7) and mdoc.samples(7). ## Custom/personal man pages (Method 1) ## If we create `~/man/`, `manpath` should find it automatically. See manpath(1) and `/etc/manpath.config`. Put man files in section directories, like `~/man/man1/`. The files need not be gzipped; `~/man/man1/foo.1` is fine. To avoid collisions with system man pages, customize the section, like `~/man/man1/ls.1m` (the "m" is arbitrary). View the custom man page like `man 1m foo`. For `man` to find personal pages first, add the custom section (e.g. "1m") at the start of SECTION in `/etc/manpath.config`. Run `mandb` to update the database used for things like `whatis`. ## Custom/personal man pages (Method 2) ## We keep our custom man pages wherever we want (e.g. `$HOME/repo/man/`), and use a custom shell script, like: ``` #!/bin/bash # Check for local/personal man pages personal_man_path=$HOME/repo/man/ # If we want custom sections like $MANPATH/manfoo/bar.foo, set # $personal_man_sections as a colon-delimited list: # personal_man_sections='foo:paul:99' # Colorize man pages man() { env LESS_TERMCAP_mb=$'\E[01;31m' \ LESS_TERMCAP_md=$'\E[01;38;5;74m' \ LESS_TERMCAP_me=$'\E[0m' \ LESS_TERMCAP_se=$'\E[0m' \ LESS_TERMCAP_so=$'\E[30;47m' \ LESS_TERMCAP_ue=$'\E[0m' \ LESS_TERMCAP_us=$'\E[04;38;5;146m' \ man "$@" } if [[ -v $personal_man_sections ]] then man --section=${personal_man_sections} --manpath=${personal_man_path} $@ 2> /dev/null else man --manpath=${personal_man_path} $@ 2> /dev/null fi # If didn't find a custom man page, check the regular man path and sections: if [[ $? -ne 0 ]] then man $@ fi ``` It still may be desirable to do `ln -s ~/repo/man ~/man`, so that `mandb -u` makes `whatis foo` find our custom pages. ## Excerpts from man(1), `/etc/manpath.config`, man-pages(7), man(7), and groff_man(7) ## man(1) - an interface to the on-line reference manuals (somewhat paraphrased): ``` Each page argument given to man is normally the name of a program, utility or function. A section, if provided, will direct man to look only in that section of the manual. The default action is to search in all of the available sections following a pre-defined order ("1 n l 8 3 2 3posix 3pm 3perl 3am 5 4 9 6 7" by default, unless overridden by the SECTION directive in /etc/manpath.config), and to show only the first page found, even if page exists in several sections. The table below shows the section numbers of the manual: 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] The following conventions apply to the SYNOPSIS section and can be used as a guide in other sections. bold text type exactly as shown. italic text replace with appropriate argument. [-abc] any or all arguments within [ ] are optional. -a|-b options delimited by | cannot be used together. argument ... argument is repeatable. [expression] ... entire expression within [ ] is repeatable. MANSECT If $MANSECT is set, its value is a colon-delimited list of sections and it is used to determine which manual sections to search and in what order. The default is "1 n l 8 3 2 3posix 3pm 3perl 3am 5 4 9 6 7", unless overridden by the SECTION directive in /etc/manpath.config. ``` From `/etc/manpath.config`: ``` # Section names. Manual sections will be searched in the order listed here; # the default is 1, n, l, 8, 3, 0, 2, 5, 4, 9, 6, 7. Multiple SECTION # directives may be given for clarity, and will be concatenated together in # the expected way. # If a particular extension is not in this list (say, 1mh), it will be # displayed with the rest of the section it belongs to. The effect of this # is that you only need to explicitly list extensions if you want to force a # particular order. Sections with extensions should usually be adjacent to # their main section (e.g. "1 1mh 8 ..."). # SECTION 1 n l 8 3 2 3posix 3pm 3perl 3am 5 4 9 6 7 ``` man-pages(7) - conventions for writing Linux man pages (somewhat paraphrased): ``` Conventions for source file layout Limit source code line length to 75 characters where possible to avoid line-wrapping when patches emailed inline. New sentences should be started on new lines; This makes it easier to see the effect of patches. Title Line The first command in a man page should be a TH command: .TH title section date source manual where: title The title of the man page in all caps (e.g., MAN-PAGES). section The section number (e.g., 7). date The date of the last nontrivial change made to the man page in the form YYYY-MM-DD. source The source of the command, function, or system call (e.g., GNU or Linux) manual The title of the manual (e.g., Linux Programmer's Manual). Sections within a manual page: NAME e.g., "ls - list directory contents" SYNOPSIS Syntax of the command and its argument; boldface for as-is text, and italics for replaceable arguments; brackets [] surround optional arguments; pipes | separate choices; ellipses ... can be repeated. CONFIGURATION (Normally only for section 4, i.e., special files like in /dev.) DESCRIPTION What it does. OPTIONS Command-line options (for sections 1 and 8). EXIT STATUS Possible exit values and their causes (sections 1 and 8). RETURN VALUE (For sections 2 and 3) ERRORS (For sections 2 and 3) ENVIRONMENT List of environment variables that affect the program and how. FILES List of configuration, startup, and files on which the program directly operates. VERSIONS (For sections 2 and 3) ATTRIBUTES (For sections 2 and 3) CONFORMING TO Describe any related standards or conventions (e.g., POSIX). NOTES Miscellaneous notes. BUGS Limitations, known defects, inconveniences. EXAMPLE One or more examples demonstrating how it's used. AUTHORS List of authors; omission of this section is recommended. SEE ALSO Alphabetical list of related man pages, or possibly other sources. Hyperlinks For hyperlinks, use the .UR/.UE macro pair (see groff_man(7)). This produces proper hyperlinks that can be used in a web browser, when rendering a page with, say: $ man -Hfirefox-esr pagename Real minus character For negative number or options with a leading dash (e.g. "ls -l"), escape the dash: ls \-l ``` man(7) - macros to format man pages (somewhat paraphrased): ``` .\" text This is a comment. The only mandatory heading is NAME. .SH NAME foo \- my brief description It is important to follow this format, and use a backslash before the single dash which follows the name. This is used by mandb(8) to create a database of short descriptions for whatis(1) and apropos(1). ``` groff_man(7) - groff man macros to support generation of man pages (somewhat paraphrased): ``` This section describes the available macros for manual pages. .EX .EE Example/End Example .HP [nnn] Hanging paragraph. Paragraph with hanging left indent (indentation set to nnn). .IP [designator] [nnn] Indented paragraph. Paragraph, with designator marking its beginning, indented nnn. .LP .PP .P Mutual aliases. A line break, followed by a vertical space downward. .RE [nnn] Restore the previous left margin, or move it left by nnn. .RS [nnn] Move left margin to the right by nnn. .SH [text for heading] An unnumbered section heading sticking out to the left (indentation of following text is reset to default). .SS [text for heading] A secondary unnumbered section heading. .TH title section [extra1] [extra2] [extra3] Set title of the man page and the section. The section must hav ea value between 1 and 8, with an optional string appended (e.g. ".pm"). .TP [nnn] Paragraph with a label, indented to nnn. The first line following this macro is used at the label. .TQ A header/label continuation for a .TP macro. (For example, the .LP, .PP, and .P labels above.) MACROS TO SET FONTS .B [text] Bold face [text] or the following line. .BI text Alternate bold face and italic text. .BI this "word and" that renders 'this' and 'that' as bold, but 'word and' as italic. .BR text Alternate bold face and roman. .I [text] Italic face [text] or the following line. .IB text Alternate italic and bold. .IR text Alternate italic and roman. .RB text Alternate roman and bold. .RI text Alternate roman and italic .SB [text] Text on this line or next in bold, one point size smaller than the default font size. .SM [text] Text on this line or next one point size smaller than the default font size. MACROS TO DESCRIBE HYPERLINKS AND EMAIL ADDRESSES .MT address .ME [punctuation] Email address. Text following the address, until .ME is the name: .MT paul@example.com Paul Gorman .ME .UR url .UE [punctuation] Web link. MACROS TO DESCRIBE COMMAND SYNOPSES .OP key value Optional argument. Rendered surrounded by brackets []. .SY command Begin synopsis. Rendered with hanging indent. .YS Ends synopsis and restored normal indentation. Example: .SY foo .OP \-asdf .OP \-g bar .OP \-y bas .OP \-z bam .RI [ file .IR .\|.\|. ] .YS ``` Examples: /usr/share/man/man1/* /usr/share/man/man2/fcntl.2.gz (suggested as canonical example by man-pages(7)) When editing groff, if vim doesn't do syntax highlighting, `:set syntax=groff`. ## Example ## ``` .\" Margin notes about ls .TH LS 1m 2015-06-15 "Linux" "Marginalia" .SH NAME ls \- margin notes about .SH SYNOPSIS .B ls [options] .SH EXAMPLES .TP .B ls \-cr1p List new files at bottom (i.e. by ctime, reversed, single\-column, append slash to directories). .TP .B ls \-i List by inode. Handy for removing weirdly named files like: .HP find \-inum 17175729 \-exec rm \-i {} \e; .SH AUTHOR Paul Gorman \%http://paulgorman.org/ ```