Showing all programs' man pages I'm trying to discover useful command line tools in Arch Linux, and it seems one good way of going about that is to look through all of the man pages related to programs (that is, section 1, as in man 1 bash) in local alphabetic order (that is, not overriding the sorting locale with LC_COLLATE=C or similar). This is the simplest (in terms of number of tokens) I've been able to do so far:

man $(man -s 1 -k . | cut -d' ' -f 1 | sort | tr '\n' ' ')


Questions:


Are there any POSIX incompatibilities here? Or any simple way to make this much more cross-platform?
Is there a simpler way to do this? For example, is there a magic man switch to actually show the pages found with -k, rather than printing their summary, or to sort the output?


This question came about because of a suggestion to use

cd /usr/bin
man


to show all the man pages. First, this just responds


  What manual page do you want?


with exit code 1. Second, amending to man * works for some executables, but several of them do not have man pages. Third, this doesn't necessarily give a complete list of section 1, especially in other distros where some tools are only installed in /usr/sbin or /bin.
POSIX.1-2008 only mandates support for the -k option of man, so you can't rely on man having any -s option on a POSIX compatible system, and in fact it is absent in both FreeBSD and Dragonfly BSD. That aside, your command should be reasonably portable barring the following issues:

Some older shells do not support $() for command substitution

Most notably C shell and the original Bourne shell do not support dollar-parentheses expansion. Use `` instead.

Output of man -k may differ between operating systems

On OpenBSD at least, there are no spaces separating the command names and the section numbers in parentheses, so it's probably better to delimit by left parenthesis. But beware of command synonyms that look like byacc, yacc (1) (MINIX), which will produce undesirable results if not further delimited by comma.

man may only display the first manual page found

Again on OpenBSD at least, the default behavior of man is to display only the first manual page found. From the man manual:


  -a Display all of the manual pages for a specified section and name combination. Normally, only the first manual page found is displayed.


Note: this is not POSIX compliant behavior.

man -k . may actually search for the literal . character

Both man -k . and man -k '' should, according to the POSIX specification, match anything in the man database, but this is not the case in OpenBSD, MINIX and SmartOS.

Piping to tr is unnecessary

Unless the IFS variable has been tampered with, the last command of the pipeline is superfluous.



Proposed solutions

Tested OS: Fairly recent versions of CentOS, Kali Linux, Manjaro Linux, openSUSE, Ubuntu, nixOS; OpenBSD, FreeBSD, Dragonfly; SmartOS; MINIX

Tested shells: sh, csh, tcsh, ksh, bash, dash, zsh

There are three ways to search for man pages in a section: man -ssection, man -Ssection or just mansection, presented roughly in the order of decreasing support by the OSes. Linux distros seem to prefer the first way, and BSDs the second. The CentOS man manual also mentions the -s option is for compatibility with System V, so it is the safest bet.

A general solution that works in all tested OSes except FreeBSD and Dragonfly:

man -a -s 1 `man -s 1 -k '(' | awk -F '[,(]' '{print $1}' | sort`


A targeted solution that works in all tested BSDs:

man -a -S 1 `man -k sec~^1$ | awk -F '[,(]' '{print $1}' | sort`


Simplest solution for a specific OS (OpenBSD):

man -a -k sec~^1$ ; # May contain duplicates