2

On my Pop!_OS 20.04 LTS system, if I use man -aw printf it will return:

/usr/share/fish/man/man1/printf.1
/usr/share/man/man1/printf.1.gz
/usr/share/man/man3/printf.3.gz

But if I use man -k printf or man -f printf or apropos printf it will only return information about:

/usr/share/man/man1/printf.1.gz
/usr/share/man/man3/printf.3.gz

Why those commands cannot find something that man -a can?

I have tried mandb and it has nothing to update.

fra-san
  • 9,931
  • 2
  • 21
  • 42

3 Answers3

2

What follows assumes that your man & friends come from man-db. Considering that Pop!_OS is based on Ubuntu and that Ubuntu 20.04 has man-db installed by default, this should be true.

When operating in "whatis" or in "apropos" mode (man -f and man -k, respectively), man actually invokes the whatis binary and delegates the search to it. On the other hand, when operating in its default mode (e.g. man page) or in "where" mode (man -w page), the search is performed by the man binary itself. The search routines of man and whatis are implemented independently of each other.

Two main reasons may make whatis list fewer manual pages than man -a:

  1. incomplete configuration: if the search path configured in /etc/manpath.config (used on Debian and derivatives; /etc/man_db.conf on some other distributions) includes all the directories containing manual pages on your system but there is no MANDB_MAP for some of them in that file, then an index database is not initialized (nor searched, if existing) for them; man -a will find the pages they contain anyway, because it directly searches the directories listed in the search path, while whatis won't, because it only searches the index database;

  2. even when all the directories containing manual pages have proper MANDATORY_MANPATH and MANDB_MAP entries in /etc/manpath.config, whatis may still list fewer results than man -a because it simply omits duplicate name-section combinations from its output. In your case, printf(1) is found in both /usr/share/man and /usr/share/fish/man and only the one from the directory that comes first in the search path is listed.

You can use the manpath command to display the search path that man & friends will use, and make sure it includes all the relevant directories. By default it is built based on the MANDATORY_MANPATH entries in /etc/manpath.config.

man & friends can also be invoked with an explicitly defined search path by setting MANPATH to alter the search results. For instance, if you are in case (2),

MANPATH=/usr/share/fish/man:/usr/share/man whatis printf

will likely print the one-line description for /usr/share/fish/man/man1/printf.1 and not the one for /usr/share/man/man1/printf.1.gz.

You can also look at what is going on under the hood by using the --debug option. It will likely show that your programs are using a search path that lists /usr/share/man before /usr/share/fish/man and that all three files are found, but a line for the second found printf in section 1 is just not printed by whatis (or man -f).

Finally, to address case (2), you may define a helper function that wraps man to make it list duplicate name-section combinations too:

slowman () (
    IFS=:
    for path in ${MANPATH-$(manpath)}
    do
        printf '%s\n' "Searching ${path}:" 1>&2
        MANPATH="$path" man "$@"
    done
)
fra-san
  • 9,931
  • 2
  • 21
  • 42
  • Now I know this is happening because there is 2 search implementations. This answers the question. And I do not have `/etc/man_db.conf` but I have `/etc/manpath.config`. My `manpath` was `/usr/local/man:/usr/local/share/man:/usr/share/man` when I asked the question. Now I updated by inserting `MANDATORY_MANPATH /usr/share/fish/man` + `mandb` and `manpath` has `:/usr/man/fish/man` now. Even with this `whatis` cannot find the manual inside `/usr/man/fish`. – Jonas A. Xavier Oct 09 '20 at 22:57
  • @JonasA.Xavier Answer edited to reflect the config file path on your distribution. Note that 1) you also need `MANDB_MAP` entries in `/etc/manpath.config` to make `whatis` work; 2) `whatis` will ever show only _one_ `printf(1)` result - the first one found in the directories listed in `MANPATH` when you invoke it. – fra-san Oct 10 '20 at 10:37
  • I got `/usr/share/man/man1/exa.1.gz` and `/usr/share/man/man4/exa.4.gz`, `man exa` gets exa.1.gz, but `man -k exa` only gets exa.4.gz not both of them, is there anything I can do to make `man -k exa` show both exa, or use another tool to list both exa? – CodyChan Apr 27 '21 at 07:08
  • @CodyChan Never mind, the man-db is not updated since I install exa seconds ago, I just need to update man-db manually – CodyChan Apr 27 '21 at 07:17
0

man man:

   -w, --where, --path, --location
          Don't actually display the manual page, but do print  the  loca‐
          tion  of  the source nroff file that would be formatted.  If the
          -a option is also used, then print the locations of  all  source
          files that match the search criteria.
Ipor Sircer
  • 14,376
  • 1
  • 27
  • 34
0

Depends on your exact version of man(1) (I very much doubt it is the original Unix one...), and on configuration (MANPATH environment variable, contents on /etc/man_db.conf for Linux' -- Debian's really -- version, ...).

vonbrand
  • 18,156
  • 2
  • 37
  • 59