28

I am trying to install a man page for a bash script on Mac OS X 10.9.5. The procedure that I tried to follow is summarised here: man page tutorial. I also summarise the steps that I tried below:

cp custom_command.1 /usr/local/man/man1/custom_command.1
gzip /usr/local/man/man1/custom_command.1

When trying man custom_command I receive the output No manual entry for custom_command. I also tried other installation methods mentioned in man page tutorial.

It is interesting to note that the steps above worked for the emacs console, i.e. I do get the correct manual when I type man custom_command. However, the command is not recognised by the autocomplete and I receive the following warning before I am able to read the manual: WARNING: terminal is not fully functional.

Any advice on how to resolve the issues above (i.e. both with the system terminal and the emacs console) would be appreciated.


Remark 1

For a reference, the man script that I am trying to install was taken from the tutorial and is restated below for a reference:

.\" Manpage for nuseradd.
.\" Contact vivek@nixcraft.net.in to correct errors or typos.
.TH man 8 "06 May 2010" "1.0" "nuseradd man page"
.SH NAME
nuseradd \- create a new LDAP user
.SH SYNOPSIS
nuseradd [USERNAME]
.SH DESCRIPTION
nuseradd is high level shell program for adding users to LDAP server.  On Debian, administrators should usually use nuseradd.debian(8) instead.
.SH OPTIONS
The nuseradd does not take any options. However, you can supply username.
.SH SEE ALSO
useradd(8), passwd(5), nuseradd.debian(8)
.SH BUGS
No known bugs.
.SH AUTHOR
Vivek Gite (vivek@nixcraft.net.in)

  • There's nothing named "the emacs console" that I'm aware of, so that phrasing is ambiguous, but I *imagine* you're referring to `M-x shell` -- which provides only a dumb terminal, and hence "WARNING: terminal is not fully functional" for anything which wants something more than that (for instance if `man` invokes a pager like `less`). You *could* use `M-x term` to get a fully-featured terminal emulator inside Emacs, but for man pages it is better to use either `M-x man` or `M-x woman` rather than running the shell command. – phils Dec 11 '18 at 22:58

6 Answers6

26

First of all you may want to check if the man page your are trying to install is properly formatted and can be opened by man command. To do this pass the path to the man file to man command. It must contain a slash in order to be recognized as a path, for example:

man /usr/local/man/man1/custom_command.1

Then you should make sure the path you are installing your man page to is on the search list of man command. In order to find the man page its path must be either:

  • specified with -M option to the man command
  • set in the environmental variable MANPATH
  • listed in its config file (/private/etc/man.conf on OS X) under MANPATH statement or under MANPATH_MAP statement (which applies only to locations in your PATH environmental variable)
  • located in the location relative to where binary is installed, i.e.: if binary is installed in path/bin the man page is searched for in path/man, path/cat and path/bin/man, path/bin/cat
  • listed in files added in /private/etc/manpaths.d/ directory

The name of the man page file must be same as command name with optional section number. It may be gzipped.

To see where man will search for your custom_command man page run

man -d custom_command
baf
  • 4,531
  • 1
  • 21
  • 24
12

OS X user command man pages are typically created in:

/usr/local/share/man/man1

If you prefer to create man pages in a different directory edit:

/private/etc/man.conf

Then add the new path to MANPATH_MAP, for example:

MANPATH_MAP     /usr/local/bin         /usr/local/man

To have man search a non-default path with a default fallback (/usr/local/share/man):

MANPATH         /usr/local/man      
MANPATH         /usr/local/share/man 
MANPATH_MAP     /usr/local/bin         /usr/local/share/man
l'L'l
  • 44,951
  • 10
  • 95
  • 146
7

Manual pages in MacOS X

The man command in MacOS X uses a sophisticated method of finding manual page files, based on the invocation options and environment variables, the /private/etc/man.conf configuration file, and some built in conventions and heuristics.

In MacOS X you have a command:

/usr/bin/manpath 

That lists all your current locations for searching for man pages. It can be invoked by just typing

manpath

in a Terminal.

It does not however add this to your $MANPATH shell variable.

But you'll still have access to the manpages with the man command. What get's included in manpath is defined in

/private/etc/man.conf

It's not advised to export an environment variable called MANPATH without adding the output of:

`manpath` 

to the list.

So if you want to export $MANPATH to your shell environment, do it like:

export MANPATH="`manpath`:/path/to/man/pages/to/include"

That way you'll get a complete list of manpages defined by the OS and any paths you add yourself.

For more info, open up a terminal and check:

man manpath

and the man.conf file with:

more /private/etc/man.conf

Usually a better option for including man pages in peculiar places, is to create a symlink to the directory containing the man pages in /usr/local/share/man which is indexed by the "man ecosystem" by default.

C. Sederqvist
  • 2,830
  • 19
  • 27
4

I had installed packages via brew, but the man command was drawing a blank because I had installed brew to a different directory. To get round this, still linking the packages (which linked content up a few directories), I could then add to MANPATH in my .bash_profile, like so...

MANPATH="/Users/me/Developer/share/man:$MANPATH"
Relequestual
  • 11,631
  • 6
  • 47
  • 83
  • This is the way to go if you want to add man pages for specific packages - in my case OpenSSL `MANPATH=/usr/local/Cellar/openssl/1.0.2o_1/share/man:$MANPATH` – Conor Svensson May 11 '18 at 13:05
  • At login, the `$MANPATH` environment variable isn't normally set in macOS and haven't been for some time. If you use [Brew](https://brew.sh/) usually it should define and update the `$MANPATH` for each Homebrew formulae it uses to install packages, IIRC. – C. Sederqvist Sep 10 '21 at 04:19
2

While existing answers do provide some hints/options which can help solve the OP's problem, they do not actually answer the question in title.

Indeed, in order for the man program to open the man page, it should know where to look for it. This is an obvious statement, but it doesn't help much. The question is whether you should use some "standard" location (and if so, what are those "standard" lookup paths, and where are they defined), or should you place the man page along with your program, and somehow point the man program to your custom location?

The OP seems to have tried placing the man page to what he thought was a "standard" location (/usr/local/man), but the man was unaware of it.

It should have worked if, instead of /usr/local/man/man1/custom_command.1, a /usr/local/share/man/man1/custom_command.1 was used. How could you know this? The answer is in the /etc/man.conf:

#
# Every automatically generated MANPATH includes these fields
#
MANPATH /usr/share/man
MANPATH /usr/local/share/man
MANPATH /usr/X11/man
MANPATH /Library/Apple/usr/share/man

/etc/man.conf is used to configure the default manpath (the provided example is from the default man.conf in macOS Big Sur). That being said, I don't think relying on man.conf default configuration and simply copying the man page for your custom program/script to one of these directories is the right thing to do.

The reason is that the default manpath is configured according to the man.conf only if the $MANPATH environment variable is not set or is empty. If the $MANPATH environment variable is set/not empty, the paths in the /etc/man.conf are not used to look up the man pages.

By default, $MANPATH is not set. But if your program/script + man page will be distributed to other users, you can't be sure whether or not it's set there.

So, what would be a reliable solution? In my opinion, shipping the man pages along with the script, and using the path_helper (man path_helper for more info) to point man to the custom manpath is the best way to go for third-party programs.

From the program/script author the only thing that's needed is to place the file, containing the path to the program man pages, into the /etc/manpaths.d directory. path_helper should do the rest.

It seems that path_helper was designed specifically for such use case, and it's being used by third-party programs (I learned about it after installing Wireshark and while trying to make its man pages discoverable), but there is one caveat:

path_helper will not make the man aware about your custom manpath, if the $MANPATH environment variable was not previously set (and as we know, it's not set by default). From path_helper man page:

(The MANPATH environment variable will not be modified unless it is already set in the environment.)

And this is the reason why you would actually want to set the $MANPATH, to allow the path_helper to augment it with custom manpaths afterwards.

In my case I added export MANPATH (just to set it, without any value) to /etc/zshenv (I am using macOS Big Sur, zsh is the default shell), and path_helper successfully added all the custom manpaths from /etc/manpaths.d files.

wombatonfire
  • 4,585
  • 28
  • 36
1

Besides all the entries pointed out in baf's answer, there's also /etc/manpaths, which is quite convenient to use for including man pages installed via Homebrew.

For example, below is the content of my /etc/manpaths:

/usr/local/opt/coreutils/libexec/gnuman
/usr/local/opt/findutils/libexec/gnuman
/usr/local/opt/gawk/libexec/gnuman
/usr/local/opt/gnu-sed/share/man
/usr/local/opt/readline/share/man
/usr/local/share/man
/usr/share/man

Meanwhile make sure in /etc/profile, MANPATH is defined before path_helper is loaded:

export MANPATH=  # hack: path_helper doesn't setup MANPATH without this
eval `/usr/libexec/path_helper -s`

BTW, in macOS, the default pager is /usr/bin/less is a bit old, and doesn't even support \b for word boundary in regex, so you might want to setup MANPAGER in ~/.bashrc (or somewhere you prefer):

export MANPAGER=/usr/local/bin/less
ryenus
  • 15,711
  • 5
  • 56
  • 63