Skip to main content

Linux command: man

27 August 2026

Every Linux system ships with a complete reference manual, installed on disk, available without a network connection, and written by the same people who wrote the software. Most users walk past it. They search the web for a flag that is documented three lines into a page they already have on their own machine. The command that opens that manual is man.

1. The Basics

The manual page for man describes it in one line: "an interface to the system reference manuals". That word interface is the important one. man does not contain any documentation itself. It finds a file, formats it, and hands it to a pager so you can scroll through it.

You use it by naming the thing you want to read about:

$ man ls

Your terminal fills with the manual page for ls, and you are now inside a pager. Press q to get out again.

1.1 A Manual Page Is a File on Disk

Nothing about this is magic. Ask man where it got the page from with -w (short for where):

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

That is a gzip-compressed text file. You can look at the raw source yourself:

$ zcat /usr/share/man/man1/pwd.1.gz | head -8
.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.48.5.
.TH PWD "1" "January 2026" "GNU coreutils 9.4" "User Commands"
.SH NAME
pwd \- print name of current/working directory
.SH SYNOPSIS
.B pwd
[\fI\,OPTION\/\fR]...
.SH DESCRIPTION

Those dot-commands are roff markup, a typesetting language older than Unix itself. .TH is the title header, .SH starts a section heading, \fB switches to bold. When you type man pwd, four things happen in a row:

  1. man searches a list of directories for a file called pwd.1, pwd.5 and so on.
  2. It decompresses that file.
  3. It runs the roff source through groff, which turns the markup into formatted text sized to your terminal.
  4. It pipes the result into a pager, normally less.

Every option that man has changes one of those four steps: where it looks, which file it picks, how it formats, or what it displays with. Once you see the pipeline, the flags stop being a random list.

The right mental model: man knows nothing about ls. It knows how to find a file, how to typeset it, and how to show it to you. The knowledge lives in the file, not in the command.

1.2 A Reference, Not a Tutorial

Beginners often read one manual page, find it dense and unfriendly, and never come back. That reaction is fair, but it misjudges what the page is for. A manual page is a reference: it is complete, precise, and organised for looking things up, not for learning a subject from zero.

A manual page answers "how exactly", never "why would I". When the second question is the one you have, you need a different document.

You are not supposed to read man ls from top to bottom. You are supposed to open it, jump to the one flag you need, and close it again. Section 4 of this article shows how to do exactly that.

Back to top

2. Where the Name Comes From

The name man is short for manual. Nothing more clever than that.

man       =  MANual
whatis    =  "what is this command?"
apropos   =  an English word borrowed from French, "with regard to"
mandb     =  MANual DataBase

The full name of the original document was the Unix Programmer's Manual, and a "man page" is literally one page out of it. The manual was numbered in parts, and that numbering survives today as the manual sections you meet in section 5 of this article.

You will constantly see documentation written in the form ls(1), passwd(5), signal(7). This is not decoration. It is a precise citation: the page named ls, in manual section 1. When a manual page says "see chmod(2)", it is telling you that the interesting page is the system call in section 2, not the command in section 1. Learn to read that notation and half of the confusion around man disappears.

Back to top

3. A Short History

The manual is as old as Unix. The Unix Programmer's Manual, First Edition was dated 3 November 1971 and written by Ken Thompson and Dennis Ritchie at Bell Labs. Their department head, Doug McIlroy, pushed hard for documentation to exist at all, and the discipline stuck: on early Unix, if you wrote a program, you wrote its manual page.

That first manual already had the shape you still see today. Pages were grouped into numbered sections, and each page used the same headings in the same order: NAME, SYNOPSIS, DESCRIPTION, FILES, SEE ALSO, DIAGNOSTICS, BUGS. Fifty years later, a manual page written this week still follows that skeleton.

The BUGS section deserves a moment. It was an official, expected heading from the start, where the author listed what their own program got wrong. That is a remarkable convention, and it is still there. Read the BUGS section of a page before you trust the tool.

EraMilestone
1964 RUNOFF on CTSS, the text formatter that roff descends from
1971 The Unix Programmer's Manual, First Edition, with numbered sections and the man command
1973 troff targets a phototypesetter for printed manuals; nroff renders the same source on terminals
1990 4.3BSD-Reno adds the mdoc macros: semantic markup ("this word is a flag") instead of visual markup ("this word is bold")
1990s GNU groff arrives as the free replacement for troff, and becomes the formatter on Linux
Today man-db on most Linux distributions, mandoc on the BSDs

The typesetting detail is worth knowing because it explains the odd corners. Bell Labs paid for the PDP-11 that Unix moved onto partly because it would run a text-processing system for the patent department. The manual was meant to be printed, on a real typesetter, with proper fonts and justified text. Your terminal is showing you a downgraded rendering of a document that was designed for paper. That is why a manual page hyphenates words at the end of a line, and why the text is justified to a fixed width. Section 7.1 shows what that costs you when you copy and paste.

There are two implementations in wide use. Linux distributions ship man-db, which is what this article documents:

$ man --version
man 2.12.0

The BSDs use mandoc instead, and macOS inherits its manual tooling from that side of the family. The everyday commands are the same (man ls, man 5 passwd, apropos, whatis), because POSIX standardises that much. The differences show up in the extras: the environment variables, the index database, and options such as -K. When a flag in this article does not work on macOS, that is why.

Back to top

4. Simple Use Cases

4.1 Opening a Page and Moving Around It

The simplest possible use is the command name on its own:

$ man cp

You are now inside less, the same pager you get from less somefile.txt. At the bottom of the screen man sets a prompt that tells you exactly which page you landed on:

Manual page cp(1) line 1

That line is worth reading before anything else. It confirms both the name and the section, so you know whether you got the page you meant. These are the keys you need:

KeyDoes
Space / b One screen forward / backward
Down / Up One line at a time
g / G Jump to the start / the end of the page
/word Search forward for word
n / N Next / previous search hit
h The pager's own help screen
q Quit

Everything you already know about less applies here, because it is less. If the keys behave differently on your system, your pager is a different program; section 6.3 explains how to change it.

4.2 The Parts of a Manual Page

Manual pages are not free-form documents. The headings are conventional, they appear in a fixed order, and the convention itself is documented in man 7 man-pages. These are the ones you will meet:

HeadingWhat it holds
NAME The name and a one-line summary. This one line is what whatis and apropos search.
SYNOPSIS The exact call syntax. The densest and most useful part of the page.
DESCRIPTION What the command does and how it behaves.
OPTIONS Every flag, one by one. Often folded into DESCRIPTION.
EXIT STATUS What the numeric return codes mean. Essential when scripting.
ENVIRONMENT Environment variables the command reads.
FILES Configuration files and paths the command uses.
EXAMPLES Worked invocations. Start here if the page has one.
STANDARDS Which standard the behaviour comes from: POSIX, ISO C, BSD, or Linux only. HISTORY says when it appeared.
BUGS Known problems, admitted by the author.
SEE ALSO Related pages, written as name(section). The map out of this page.

Because the headings sit at the left margin, you can jump straight to one with a pager search anchored to the start of the line:

$ man rsync
/^EXAMPLES        # then press Enter, and n for the next hit
/^EXIT STATUS
/^ENVIRONMENT

This is the habit that turns manual pages from a wall of text into a reference you can actually use. Do not scroll. Jump.

4.3 How to Read a SYNOPSIS

The SYNOPSIS is a compressed grammar of the command. It uses a notation that nobody ever explains, which is why many people skip it. Here is the whole notation:

NotationMeans
Bold text Type this exactly, character for character
Underlined or italic text Replace this with your own value
UPPERCASE words (GNU tools) The same thing: a placeholder you fill in
[ ] Optional. The brackets are not typed.
... The previous item may repeat
| Choose one of the alternatives
Several SYNOPSIS lines Several distinct modes of the same command

Now read a real one. This is the whole of ls:

$ man ls
SYNOPSIS
       ls [OPTION]... [FILE]...

Both parts are optional and both may repeat. So ls, ls -l, ls -l -a /etc /var are all valid, and so is ls /etc /var with no options at all. That single line told you the complete calling convention.

Now one with real structure:

$ man cp
SYNOPSIS
       cp [OPTION]... [-T] SOURCE DEST
       cp [OPTION]... SOURCE... DIRECTORY
       cp [OPTION]... -t DIRECTORY SOURCE...

Three lines means three modes. Line one copies exactly one thing to one destination. Line two copies one or more sources into a directory, and note that SOURCE... repeats while DIRECTORY does not, so the last argument is the target. Line three does the same thing with the target named up front by -t, which is what you use when the source list comes from a pipe. The entire behaviour of cp that trips people up is stated in those three lines.

Pages in sections 2 and 3 look different, because they document C functions rather than commands:

$ man 3 printf
SYNOPSIS
       #include <stdio.h>

       int printf(const char *restrict format, ...);
       int fprintf(FILE *restrict stream,
                   const char *restrict format, ...);

Here the SYNOPSIS gives you the header file to include and the exact prototypes. Same idea, different audience: it is still "how do I call this thing".

4.4 The Page You Want Is Often Not the One You Typed

One command name can have several manual pages. man gives you one of them, and it decides which without telling you. Try this:

$ whatis passwd
passwd (1)           - change user password
passwd (1ssl)        - OpenSSL application commands
passwd (5)           - the password file

Three different pages, all called passwd. Plain man passwd gives you the command in section 1. If what you actually wanted was the format of /etc/passwd, you have to ask for the section explicitly. That is the whole answer to the question "why does man 5 passwd exist", and section 5 is about exactly that.

Back to top

5. Moderate Use Cases

5.1 The Manual Sections

The manual is split into numbered sections by kind of thing, not by topic. This list comes straight from man man:

SectionContainsExample
1 Executable programs and shell commands man 1 ls
2 System calls, provided by the kernel man 2 open
3 Library calls, functions inside program libraries man 3 printf
4 Special files, usually in /dev man 4 random
5 File formats and conventions man 5 passwd
6 Games man 6 intro
7 Miscellaneous: conventions, protocols, overviews man 7 signal
8 System administration commands, usually root-only man 8 mount
9 Kernel routines (non-standard, rarely installed) -

Pages are filed by the kind of thing they document, not by subject. passwd the command and passwd the file are two unrelated documents that happen to share a name, and they sit in different sections for that reason.

Section 5 and section 8 are the two that pay off immediately for anyone who administers a server. Section 5 documents the file formats, which is the thing you are usually actually looking for when you edit a configuration file:

$ man 5 passwd        # the layout of /etc/passwd, field by field
$ man 5 crontab       # the five time fields, not the crontab command
$ man 5 fstab         # every column of /etc/fstab
$ man 5 sshd_config   # every option you can put in that file

The crontab example is the clearest case. crontab(1) is the command you run to edit your crontab and documents about four flags. crontab(5) is the page that explains what those five asterisks mean. People search the web for cron syntax for years without discovering that the answer was in man 5 crontab the whole time.

Section 7 is the hidden gem: it holds the overview pages that explain a whole subject rather than one program.

$ man 7 signal          # every signal, what it does, and the default action
$ man 7 hier            # what every directory in the filesystem is for
$ man 7 ascii           # the ASCII table, in octal, decimal and hex
$ man 7 man-pages       # how manual pages themselves are written
$ man 7 glob            # what * and ? and [a-z] really match
$ man 7 path_resolution # exactly how Linux turns a path into a file
$ man 7 capabilities    # the root privileges, split into 40 separate ones
$ man 7 namespaces      # the kernel feature containers are built on

Each section also has an intro page describing what belongs in it. man 1 intro, man 2 intro, and so on all the way to man 8 intro.

5.2 Which Pages Exist: whatis and man -f

Before you read a page, it is often worth asking which pages exist under a name. The whatis command answers exactly that, by printing the NAME line of every matching page:

$ whatis printf
printf (1)           - format and print data
printf (3)           - formatted output conversion

The command man -f (short for whatis) is the same thing:

$ man -f printf       # identical output to: whatis printf

This is a two-second check that saves real confusion. If you type man printf looking for the shell command and get a page full of %llu and va_list, whatis would have shown you both pages up front.

5.3 Reading Every Version: man -a

The -a flag (short for all) shows every matching page in turn instead of only the first. When you quit one page, the next one opens. Combined with -w it becomes a quick inventory:

$ man -aw intro
/usr/share/man/man1/intro.1.gz
/usr/share/man/man8/intro.8.gz
/usr/share/man/man3/intro.3.gz
/usr/share/man/man2/intro.2.gz
/usr/share/man/man5/intro.5.gz
/usr/share/man/man4/intro.4.gz
/usr/share/man/man6/intro.6.gz
/usr/share/man/man7/intro.7.gz

Eight pages named intro, and plain man intro shows you the first of them. Look closely at the order of that list: it is not 1, 2, 3, 4. Section 7.3 explains why, and it is one of the most useful things in this article.

5.4 Finding a Command You Cannot Name: apropos

Everything so far assumed you know the command name. The harder problem is the opposite one: you know what you want to do, but not what the tool is called. That is what apropos is for. It searches the one-line NAME descriptions of every installed page:

$ apropos mkdir
mkdir (1)            - make directories
mkdir (2)            - create a directory
mkdirat (2)          - create a directory

The command man -k (short for keyword) is the same program:

$ man -k mkdir        # identical to: apropos mkdir

By default the search terms are treated as separate keywords. Quote a phrase and narrow it to one section to get usable results instead of hundreds:

$ apropos -s 1 'copy files'
cp (1)               - copy files and directories
cpio (1)             - copy files to and from archives
gh-codespace-cp (1)  - Copy files between local and remote file systems

Useful modifiers:

OptionEffect
-s 1 or -s 1,8 Restrict to one or more sections
-e Exact match on the whole word, not a substring
-w Treat the term as a wildcard, for example whatis -w 'ls*'
--regex Treat the term as a regular expression
-a Require all keywords to match, not any of them

One honest warning: apropos only searches that single NAME line. If an author wrote a bad summary, the page is effectively invisible to it. For a real full-text search, see section 6.4.

5.5 Where Does This Page Live: man -w

The -w flag prints the path instead of opening the page. It is the fastest way to answer "is this documented on this machine at all", and it works with a section number too:

$ man -w 5 passwd
/usr/share/man/man5/passwd.5.gz

It also makes a clean test in a script, since it prints nothing and returns non-zero when there is no page.

Back to top

6. Advanced Use Cases

6.1 Choosing the Section Yourself: -S and MANSECT

You already know that a bare section number in front of the name picks a section:

$ man 5 passwd

The longer form takes a list, in the order you want them tried:

$ man -S 5,1 passwd       # try section 5 first, fall back to 1
$ man --sections=8,1 mount

If you always want a different preference, set MANSECT instead of typing it every time. An administrator who lives in configuration files might well prefer section 5 and 8 to come before section 1:

$ export MANSECT=8:5:1:7:2:3

6.2 How man Decides Where to Look

Manual pages live in a manual path, a colon-separated list of directories much like PATH. Ask for yours:

$ manpath
/usr/share/man:/home/peter/.local/share/man:/usr/local/man:/usr/local/share/man

$ man --path            # the same thing, from man itself

That list is not hard-coded. It is built from /etc/manpath.config, which contains two interesting kinds of line:

MANDATORY_MANPATH       /usr/share/man
MANDATORY_MANPATH       /usr/local/share/man
MANPATH_MAP  /usr/bin        /usr/share/man
MANPATH_MAP  /usr/local/bin  /usr/local/share/man
MANPATH_MAP  /opt/bin        /opt/man

The MANPATH_MAP lines are the clever part. They say: "for every directory in the user's PATH, add the matching manual directory". So when you install a program into /opt/bin and put that in your PATH, its manual pages in /opt/man become findable automatically. The manual path follows the executable path.

You can override the whole thing with the MANPATH environment variable, but there is a trap: setting it replaces the computed list instead of adding to it. That is why a leading or trailing colon matters, because an empty entry means "insert the default list here":

$ MANPATH=/opt/mytool/man man --path
/opt/mytool/man                                  # ONLY this. Everything else is gone.

$ MANPATH=/opt/mytool/man: man --path
/opt/mytool/man:/usr/share/man:/home/peter/.local/share/man:/usr/local/share/man

For a single command, prefer -M over exporting anything:

$ man -M /opt/mytool/man mytool

6.3 Making man Comfortable

man reads a handful of environment variables. These four are worth knowing:

VariableEffect
MANPAGER The program used to display pages. Takes priority over PAGER.
MANWIDTH Format to this width instead of the terminal width.
MANSECT The section search order (see 6.1).
MANOPT Options applied to every man call, as if you typed them.

Two of them solve real annoyances. On a very wide terminal, a manual page becomes hard to read because the lines run on forever; MANWIDTH pins it to a comfortable measure:

$ export MANWIDTH=80

And MANOPT lets you make a preference permanent without an alias. This one turns off hyphenation and justification for every page you ever open, for the reason explained in section 7.1:

$ export MANOPT="--no-hyphenation --no-justification"

Dumping a page as plain text is easy, because man notices when its output is not a terminal and drops all formatting automatically:

$ man ls > ls.txt              # plain text, no control characters
$ man -P cat ls                # same, forcing the pager to cat
$ MANPAGER=cat man ls          # same, through the environment

That makes a manual page just another text stream, so the rest of the Unix toolbox works on it:

$ man cp | grep -A2 -- '-l, --link'
       -l, --link
              hard link files instead of copying

$ man ls | wc -l               # how long is this page really?

6.4 Full-Text Search: man -K

apropos only looks at the NAME line. The -K flag (short for global apropos) searches the body of every manual page on the system. It is slow, because it decompresses and scans thousands of files, but it finds things nothing else will:

$ man -wK -S 5 'MANPATH_MAP'
/usr/share/man/man5/manpath.5.gz

Two habits make it usable. Restrict the sections with -S, and add -w so you get a list of paths instead of being dropped into each matching page in turn.

There is one subtlety that its own manual page is honest about: -K searches the roff source of each page, not the rendered text, because rendering everything would be far slower. So it can produce false positives from comments in the source, and false negatives when the source writes something differently from the way it appears on screen. A minus sign written \- in the source is the classic example, which is why searching for a flag with -K sometimes finds nothing.

Even so, this is the tool for the question "which configuration file is this obscure setting in?". Note that -K is a man-db extension and is not available everywhere.

6.5 Other Ways to Render a Page

Because formatting is a separate step in the pipeline, you can redirect it. A manual page you have downloaded, or one you are writing, is opened with -l (short for local file):

$ man -l ./mytool.1
$ man -l /tmp/downloaded.8.gz

Without -l, man would treat that path as a page name and fail.

The typesetting heritage is still live. -t (short for troff) formats the page for print instead of for a terminal:

$ man -t ls | head -2
%!PS-Adobe-3.0
%%Creator: groff version 1.23.0

$ man -t ls > ls.ps            # PostScript
$ man -t ls | ps2pdf - ls.pdf  # a printable PDF of the manual page

There is also -H, which renders a page to HTML and opens it in a browser. Be aware that on Debian and Ubuntu only groff-base is installed by default, which can produce PostScript but not HTML; man -H fails there until you install the full groff package.

6.6 Sections 2 and 3: The Programmer's Manual

Sections 2 and 3 are a different manual for a different reader, and they are the part of the system almost nobody discovers by accident. Section 2 documents the system calls, the interface between your program and the kernel. Section 3 documents library functions, which run in your own process and usually call system calls underneath.

$ man 2 open          # the kernel system call
$ man 3 fopen         # the C library function built on top of it
$ man 2 read          $ man 3 malloc
$ man 2 fork          $ man 3 pthread_create

That pairing is the whole point of the split. open() is a request to the kernel; fopen() is a wrapper around it that adds buffering and bookkeeping in user space. The section number tells you which side of that boundary you are standing on.

These pages use their own headings. A command has EXIT STATUS; a function has RETURN VALUE and ERRORS:

$ man 2 open
RETURN VALUE
       On success, open(), openat(), and creat() return  the  new  file  de-
       scriptor (a nonnegative integer).  On error, -1 is returned and errno
       is set to indicate the error.

ERRORS
       EACCES The  requested  access  to  the file is not allowed ...

The ERRORS section is the reason to open these pages at all. It lists every errno value the call can produce and what each one means, which no web search summarises correctly.

One trap has its own answer in the SYNOPSIS. Some functions are only declared when you define a feature-test macro first, and the page tells you which one:

$ man 3 asprintf
SYNOPSIS
       #define _GNU_SOURCE         /* See feature_test_macros(7) */
       #include <stdio.h>

       int asprintf(char **restrict strp, const char *restrict fmt, ...);

If you skip that first line, the compiler reports that asprintf is undeclared even though the manual page clearly documents it. The page even points at the overview: man 7 feature_test_macros explains _GNU_SOURCE, _POSIX_C_SOURCE and the rest. This is a case where reading the SYNOPSIS literally, including the comment, saves an afternoon.

Section 2 and 3 pages also carry a STANDARDS section, which tells you whether an interface is POSIX, a BSD inheritance, or Linux only. That is the difference between code that ports and code that does not. If these pages are missing on your machine, see section 7.7.

6.7 Manual Pages in Your Own Language

Manual pages can be translated, and the manual hierarchy has a subdirectory per locale next to the numbered ones:

$ ls /usr/share/man/ | grep -v '^man[1-9]$' | tr '\n' ' '
ca ca@valencia cs da de de.UTF-8 es fi fr fr.ISO8859-1 fr.UTF-8 hr hu id it
ja ja.UTF-8 ko nl pl pt pt_BR ro ru sk sl sr sv tr uk zh zh_CN zh_TW

Your LANG and LC_MESSAGES settings decide which one man prefers. You can also ask for a language directly with -L:

$ man -L nl apropos
APROPOS(1)               Hulpprogramma's paginaopmaker              APROPOS(1)

NAAM
       apropos - namen en beschrijvingen van de man-pagina's doorzoeken

SAMENVATTING

Two practical notes. First, coverage is thin. This machine has 105 Dutch pages against 9761 English ones, and they come almost entirely from apt, dpkg and man-db itself. For anything else you get English regardless of your locale.

Second, a translation can lag behind the original, because the English page ships with the software and the translation ships with a language pack. When you follow English documentation, compare notes with a colleague, or report a problem, force the original:

$ man -L C apropos     # the untranslated page
$ man -L C -w apropos
/usr/share/man/man1/apropos.1.gz

That is also the fastest way to check whether a heading you cannot find is missing or merely translated.

6.8 The Odd Section Names: 1ssl, 3perl, 3avr

Look again at the output of whatis and you will see sections that are not plain numbers:

$ whatis passwd
passwd (1)           - change user password
passwd (1ssl)        - OpenSSL application commands
passwd (5)           - the password file

The letters after the number are a sub-extension. They let one project claim its own space inside a section so that OpenSSL's passwd does not fight with the system's passwd. You will meet 1ssl, 3perl, 3pm, 3posix, and others. Ask for one with -e:

$ man -e ssl passwd            # the OpenSSL page
$ man 1ssl passwd              # the same, written the short way

6.9 Writing a Manual Page for Your Own Script

If you write scripts that other people (or future you) will run on a server, giving them a manual page costs about ten minutes and makes them look installed rather than improvised. The format is plain roff. This is a complete, working page:

.TH DEPLOY 1 "August 2026" "1.0" "Site tools"
.SH NAME
deploy \- push the website to production
.SH SYNOPSIS
.B deploy
[\fB\-n\fR] \fISITE\fR
.SH DESCRIPTION
Pushes the checked-out site to the production server.

The .TH line takes five fields: the name in capitals, the section, the date, the version, and the manual title shown in the header. .SH starts a section heading, .B makes the following line bold, and \fB ... \fR and \fI ... \fR switch to bold and italic inside a line.

Install it into the local hierarchy and rebuild the index:

$ sudo cp deploy.1 /usr/local/share/man/man1/
$ sudo mandb
1 man subdirectory contained newer manual pages.
1 manual page was added.

$ man deploy
DEPLOY(1)                         Site tools                        DEPLOY(1)

NAME
       deploy - push the website to production

SYNOPSIS
       deploy [-n] SITE

Before installing, preview it straight from the working directory with man -l deploy.1. Note the escaped hyphen in deploy \- push: in roff a bare - is a typographic hyphen, and \- is the literal minus sign. Getting that wrong is why some manual pages give you a character you cannot paste back into a shell.

Back to top

7. Something Most Users Do Not Know

7.1 The Hyphen You Copied Is Not a Hyphen

This one bites people for years without being noticed. Manual pages are justified and hyphenated, because they were designed for print. When groff breaks a word across two lines, it inserts a real typographic hyphen, U+2010, which is not the ASCII - on your keyboard.

Count the non-ASCII characters in a page that has no non-ASCII content at all:

$ man 1 intro | grep -c -P '[^\x00-\x7F]'
14

$ man 1 intro | grep -o -P '[^\x00-\x7F]' | head -1 | hexdump -C
00000000  e2 80 90                                 |...|

Those three bytes are UTF-8 for U+2010 HYPHEN. Now turn hyphenation and justification off:

$ man --no-hyphenation --no-justification 1 intro | grep -c -P '[^\x00-\x7F]'
2

The remaining two are genuine punctuation in the source text. Everything else was an artefact of the layout.

Why this matters: when you copy a long flag out of a manual page and it happened to break across a line, you paste an invisible non-ASCII character into your terminal and get a baffling error about a command that clearly exists. The same thing quietly poisons documentation and support tickets. The fix is one line in your shell profile:

export MANOPT="--no-hyphenation --no-justification"

The short forms are --nh and --nj. Ragged-right manual pages are also easier to read on screen, so you lose nothing.

7.2 apropos Searches a Cache, Not Your System

man looks for pages on disk every time. apropos and whatis do not: they query a pre-built index, and if that index is stale they will confidently tell you a page does not exist.

$ ls -l /var/cache/man/index.db
-rw-r--r-- 1 man man 1552384 Aug 21 10:23 /var/cache/man/index.db

Watch it fail and then work. Here a new page has just been installed:

$ man deploy            # works immediately, man searched the filesystem
DEPLOY(1) ...

$ apropos deploy        # fails, the index has not been told
deploy: nothing appropriate.

$ sudo mandb
1 manual page was added.
0 stray cats were added.
0 old database entries were purged.

$ apropos deploy
deploy (1)           - push the website to production

On a normal desktop or server a scheduled job rebuilds this index daily, so you rarely notice. You notice it in a container, on a minimal image, or straight after installing a package by hand: apropos comes up empty while man works fine. Run sudo mandb and it is fixed.

Incidentally, "0 stray cats were added" is not a typo. A cat page is a pre-formatted copy of a manual page, cached in /var/cache/man/cat1 and friends so it does not have to be typeset again. On machines fast enough to run groff in a few milliseconds, that cache is essentially dead; on modern systems those directories are usually empty.

7.3 The Section Search Order Is Not 1, 2, 3

Remember the surprising order of man -aw intro in section 5.3: 1, 8, 3, 2, 5, 4, 6, 7. That is not random, and it is not alphabetical. It is a configured preference, sitting in one line of /etc/manpath.config:

$ grep '^SECTION' /etc/manpath.config
SECTION  1 n l 8 3 0 2 3type 3posix 3pm 3perl 3am 5 4 9 6 7

Read left to right, that is the order man tries sections in when you do not name one. This single line answers several everyday puzzles at once:

  • Why does man printf give the command and not the C function? Section 1 comes before section 3.
  • Why does man passwd give the command and not the file format? Section 1 comes before section 5. So does 8, 3 and 2.
  • Why is an administration command found so easily? Section 8 is second in the list, right after 1.
  • Why do file formats feel hidden? Section 5 is ninth, behind six other sections.

Once you have seen that line, "which page will I get?" stops being a guess. And if you disagree with the order, section 6.1 showed you how to change it with MANSECT.

7.4 man Does Not Exit With 1

Scripts that check for documentation get this wrong. A missing page is not exit code 1:

$ man nosuchthing >/dev/null 2>&1; echo $?
16

The EXIT STATUS section of man man spells out the whole scheme: 0 success, 1 a usage or configuration error, 2 an operational error, 3 a child process failed, and 16 "at least one of the pages, files or keywords did not exist or was not matched". So in a script, test for success rather than for a specific failure:

if man -w "$1" >/dev/null 2>&1; then
    echo "documented"
else
    echo "no manual page for $1"
fi

7.5 Shell Builtins Have No Manual Page

Try to read the manual for cd:

$ man cd
No manual entry for cd

$ man cd >/dev/null 2>&1; echo $?
16

This confuses every beginner, and the reason is logical once you see it. Manual pages document programs, and there is no program called cd. It is a builtin: a command implemented inside the shell itself, because changing directory has to affect the shell's own process. The same is true of export, alias, source, ulimit and type.

There are three ways to reach that documentation instead:

$ help cd                 # bash's own builtin help, the direct answer
$ man bash                # the full shell manual; then search /^   cd
$ man 7 builtins          # a stub page that points you at bash(1)

The stub is a nice touch on Debian and Ubuntu, and whatis shows what it is for:

$ whatis builtins
builtins (7)         - bash built-in commands, see bash(1)

When you are not sure which kind of thing you are dealing with, ask the shell before you ask man:

$ type -a cd
cd is a shell builtin

$ type -a ls
ls is aliased to `ls --color=auto'
ls is /bin/ls

7.6 man Runs a Sandbox Around groff

Displaying a manual page sounds harmless. It is not quite as harmless as it sounds, because roff is not a markup language in the modern sense. It is a full typesetting programming language, and the formatter that processes it is a large piece of parsing code that runs on whatever file you point it at.

man-db takes that seriously. Its own manual page says so, in the ENVIRONMENT section:

MAN_DISABLE_SECCOMP
       On Linux, man normally confines subprocesses that handle untrusted
       data using a seccomp(2) sandbox.  This makes it safer to run complex
       parsing code over arbitrary manual pages.

In other words, every time you open a manual page, the decompressor and the formatter run inside a kernel-enforced sandbox that restricts which system calls they may make. You never see it, and that is the point.

Two things follow from this. If a page fails to render with a confusing error, MAN_DISABLE_SECCOMP=1 exists as a diagnostic, but it is a way to prove where a problem is, not a fix to leave in your profile. And a .1 file you downloaded from somewhere is untrusted input like any other file: man -l ./whatever.1 is reasonable, piping a strange roff file through a formatter with the sandbox turned off is not.

7.7 The Page Exists, It Is Just Not Installed

"No manual entry for open" does not mean the page was never written. On Debian and Ubuntu, most of the pages this article recommends do not come from the program they document. They come from separate documentation packages:

$ dpkg -S /usr/share/man/man2/open.2.gz
manpages-dev: /usr/share/man/man2/open.2.gz

$ dpkg -S /usr/share/man/man3/printf.3.gz
manpages-dev: /usr/share/man/man3/printf.3.gz

$ dpkg -S /usr/share/man/man7/feature_test_macros.7.gz
manpages: /usr/share/man/man7/feature_test_macros.7.gz

So the entire programmer's manual of section 6.6, and a good part of the section 7 overviews, arrive with manpages and manpages-dev. Neither is installed on a minimal server. Install them and pages appear that were never missing from the internet, only from your machine:

$ sudo apt install manpages manpages-dev

The same logic applies more aggressively inside containers. Slim base images configure the package manager to throw manual pages away as they are unpacked, to save a few megabytes, so man in a container often documents nothing at all.

When a page you expected is not there, walk down this list before concluding it does not exist:

  • Is the program itself installed? Check with type -a name.
  • Is it a shell builtin rather than a program? See section 7.5.
  • Is there a separate documentation package, such as manpages-dev or a -doc package for that project?
  • Is the directory holding it in your manual path? Check with manpath, and see section 6.2.
  • Does man find it but apropos not? Then the index is stale: sudo mandb.
  • Are you in a container or on a stripped-down image where the pages were removed at install time?

7.8 Knowing Where man Stops

Part of expertise is knowing when a tool is the wrong one. Linux has four documentation commands that look interchangeable and are not, and the difference between them is not the format. It is where the text comes from.

CommandWhere the text comes fromReach for it when
cmd --help The binary you just ran You want a quick flag reminder, or you need to be certain the answer matches the version installed
man cmd A documentation package, installed separately from the binary You want the complete reference: every flag, the files, the exit codes, the related pages
help cmd The shell process you are typing into The command is a shell builtin, so there is no program and no manual page to find
info cmd The GNU project's own manual, a separate document You want to learn a GNU tool properly rather than look one flag up
/usr/share/doc/<package>/ The package maintainer You need READMEs, changelogs, or example configuration files that no manual page carries

help is part of the shell, not of the system. That is easy to prove, and it is the reason it can document things man cannot:

$ type help
help is a shell builtin

$ help -d cd
cd - Change the shell working directory.

$ help -s cd
cd: cd [-L|[-P [-e]] [-@]] [dir]

Use -d for the one-line description and -s for the synopsis alone, which is usually all you wanted. Ask it about something that is not a builtin and it refuses, and points you at the right tool instead:

$ help ls
bash: help: no help topics match `ls'.  Try `help help' or `man -k ls' or `info ls'.

info is where GNU keeps the real manual. For GNU projects the manual page is often a summary, and it says so itself. Look at the last lines of man ls:

SEE ALSO
       dircolors(1)

       Full documentation <https://www.gnu.org/software/coreutils/ls>
       or available locally via: info '(coreutils) ls invocation'

That page was generated from ls --help. The document that explains why the flags behave as they do is the info manual:

$ info coreutils 'ls invocation'
$ info grep
$ info bash

Info documents are structured as linked nodes rather than one long page, so they need different keys: n and p for the next and previous node, u to go up a level, Enter to follow the link under the cursor, and q to quit. If that navigation annoys you, pinfo and your editor's info reader present the same documents.

One last caveat, and it is the one that actually bites: --help and man can disagree. The manual page comes from the distribution package, while --help comes from the binary in front of you. If you compiled a newer version by hand, or you are inside a container with an older manual, believe --help.

Back to top

8. Best Practices

  • Read the prompt line at the bottom. Manual page cp(1) line 1 tells you the name and the section you actually landed on. Half of all "the manual is wrong" moments are really "I am reading a different page than I think".
  • Jump, do not scroll. Inside the pager, search for a heading anchored to the line start: /^EXAMPLES, /^EXIT STATUS, /^ENVIRONMENT. Use n to walk through the hits.
  • Learn to read a SYNOPSIS. Square brackets mean optional, three dots mean repeatable, italic means "your value here", and several lines mean several modes. Two minutes there beats twenty minutes of trial and error.
  • Check which pages exist before you read one. whatis name takes a second and prevents you from reading the C function when you wanted the command.
  • Remember section 5 for configuration files. When you are editing a file rather than running a command, the page you want is almost always man 5 something.
  • Browse section 7 once, deliberately. man 7 hier, man 7 signal and man 7 glob each teach a piece of Linux that most people pick up slowly and incorrectly.
  • Turn off hyphenation permanently. Put export MANOPT="--no-hyphenation --no-justification" in your shell profile so that what you copy is what you typed.
  • Install the documentation packages on a working machine. On Debian and Ubuntu, manpages and manpages-dev bring the system calls, the library functions and most of the section 7 overviews. They are not there by default on a server.
  • Force the original when it matters. A translated page can lag behind the software. Use man -L C name when you follow English documentation or discuss a page with someone else.
  • Rebuild the index after installing things by hand. If apropos finds nothing but man works, run sudo mandb.
  • Give your own scripts a manual page. Anything that lives in /usr/local/bin on a server you maintain for someone else deserves eight lines of roff in /usr/local/share/man/man1.
  • Use the whole documentation set, not only man. The manual page is the reference, --help is the reminder that always matches the installed binary, help is the only source for shell builtins, info is the GNU tutorial, and /usr/share/doc holds what none of them carry.
$ man man                        # the manual for the manual
$ man 7 man-pages                # how manual pages are structured
$ man 1 intro                    # what section 1 is for (also 2 to 8)
$ man --help                     # the flag summary
$ info info                      # how to drive the info reader
Back to top

9. Common Mistakes

9.1 Myth Versus Reality

MythReality
"There is one manual page per command." There can be several. passwd has three on a normal system, in sections 1, 1ssl and 5.
"man searches sections in numerical order." It uses the SECTION line in /etc/manpath.config, which starts 1 n l 8 3 0 2 ....
"apropos searches the manual." It searches one line per page, the NAME summary, in a cached index. Full text needs man -K.
"No manual entry means the command does not exist." It may be a shell builtin (cd, export), or documented only in --help or info.
"Manual pages are plain text files." They are roff source, typeset by groff every time you open one.
"The manual page always matches the installed binary." The page comes from the package; the binary may be newer or self-compiled. --help is the version you are running.
"You cannot pipe or grep a manual page." You can. man drops all formatting when its output is not a terminal.
"You need man ls | col -b to get plain text." Old advice. man-db already gives you clean text in a pipe, and modern groff marks up with escape sequences rather than backspaces, which col -b does not remove anyway.

9.2 Other Traps to Avoid

  • Copying a flag that broke across a line. You get a U+2010 hyphen instead of an ASCII one, and a command that "clearly exists" refuses to run. See section 7.1.
  • Testing for exit code 1. A missing page exits with 16. Test for success with if man -w "$1" >/dev/null 2>&1, not for a specific failure code.
  • Setting MANPATH without a colon. MANPATH=/opt/tool/man replaces the entire search path and hides every system page. Write MANPATH=/opt/tool/man: or use man -M for one call.
  • Trusting apropos in a container. Minimal images often ship without the index, and sometimes without the manual pages at all, because the packaging strips /usr/share/man to save space. apropos silently finds nothing.
  • Reading a page top to bottom. A manual page is organised for lookup, not for learning. Go to EXAMPLES first, then the one option you need.
  • Giving up on man bash. It is enormous, but it is also complete and searchable. /^ cd inside the pager beats any web search for shell builtin behaviour.
  • Forgetting the section when you write documentation. Writing "see the chmod manual" is ambiguous; writing chmod(1) or chmod(2) is not. Use the notation, it is what it is for.
Back to top

10. Summary

The manual is the most complete Linux documentation you will ever have, it is already installed, and it works with no network connection at three in the morning.

  • man is short for manual. It does not hold documentation itself: it finds a roff file, formats it with groff, and pipes it into a pager.
  • Manual pages date from the Unix Programmer's Manual of 1971, and the headings you read today (NAME, SYNOPSIS, DESCRIPTION, BUGS, SEE ALSO) come straight from it.
  • The manual is split into numbered sections by kind: 1 commands, 2 system calls, 3 library functions, 4 devices, 5 file formats, 6 games, 7 overviews, 8 administration.
  • Section 5 is the one most people never discover. man 5 crontab and man 5 sshd_config document the files, not the commands.
  • The notation ls(1) is a citation: page name plus section. Read it, and write it.
  • Learn the SYNOPSIS notation once: [ ] optional, ... repeatable, italic means your own value, several lines mean several modes.
  • Inside the pager, jump with /^EXAMPLES instead of scrolling.
  • whatis shows which pages exist, apropos searches their one-line summaries, and man -K searches the full text.
  • Sections 2 and 3 are the programmer's manual: system calls versus library functions, with ERRORS and RETURN VALUE instead of EXIT STATUS, and the feature-test macro your compiler needs written into the SYNOPSIS.
  • Pages can be translated. man -L nl name asks for Dutch, man -L C name forces the original, and coverage outside English is thin.
  • A missing page often means a missing package, not missing documentation. On Debian and Ubuntu, manpages and manpages-dev hold most of sections 2, 3 and 7.
  • apropos reads a cached index. After installing a page by hand, run sudo mandb.
  • The section search order comes from /etc/manpath.config and is not 1, 2, 3. That explains man printf and man passwd.
  • Turn hyphenation off with MANOPT, or the flags you copy will contain a character your shell does not understand.
  • A missing page exits with 16, not 1. Shell builtins have no page at all: use help cd.
  • Know where man stops, and note that the four documentation commands differ by source: --help comes from the binary, man from a documentation package, help from the shell itself, and info from the GNU project's own manual.

This is the quick reference worth keeping:

man NAME                     open the manual page
man 5 NAME                   open it in a specific section
man -a NAME                  show every matching page in turn
man -f NAME                  which pages exist (same as whatis)
man -k WORD                  search the one-line summaries (same as apropos)
man -wK -S 5 WORD            full-text search, section 5, list the files
man -w NAME                  print the path of the page
man -l ./page.1              open a page file directly
man -L C NAME                the original page, not a translation
man -t NAME > page.ps        typeset for print instead of terminal
man -P cat NAME              no pager, straight to stdout
man NAME | grep -A2 -- -x    pipe it like any other text

apropos -s 1 'copy files'    find a command by what it does
whatis -w 'ls*'              wildcard search on page names
mandb                        rebuild the apropos/whatis index
manpath                      show where man looks for pages

/^EXAMPLES                   inside the pager: jump to a heading
n  N                         next / previous match
g  G  q                      top, bottom, quit

export MANWIDTH=80                                  readable width
export MANSECT=8:5:1:7:2:3                          your own section order
export MANOPT="--no-hyphenation --no-justification" copy-paste safe pages

apt install manpages manpages-dev    sections 2, 3 and most of 7 (Debian)
dpkg -S /usr/share/man/...   which package a page came from

help cd                      shell builtins, which have no manual page
help -s cd                   just the synopsis of a builtin
cmd --help                   the version you are actually running
info coreutils 'ls invocation'   the full GNU manual (n p u Enter q)

Reading the manual well is one of those quiet skills that separates someone who guesses at a server from someone who knows what it is doing. If your Linux server needs someone who reads the documentation before changing the configuration, and who leaves behind notes the next person can follow, that is exactly the kind of work I enjoy helping with.

Back to top
Linux command: man
Peter Martin
Peter Martin
Joomla Specialist

Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.